Змінити клас при наведенні миші в директиві


77

У мене проблеми з розробкою, як змусити клас змінитись за вкладеною директивою.

Це зовнішнє ng-повторення

<div data-courseoverview data-ng-repeat="course in courses | orderBy:sortOrder | filter:search"
         data-ng-controller ="CourseItemController"
         data-ng-class="{ selected: isSelected }">

Нижче наведено внутрішній ng-repeat, який використовує іншу директиву

<li data-ng-repeat="item in social" class="social-{{item.name}}" ng-mouseover="hoverItem(true);"
    ng-mouseout="hoverItem(false);"
    index="{{$index}}"><i class="{{item.icon}}"
    box="course-{{$index}}"></i></li>

Ось директива, яка закликає до події наведення

ecourseApp.directive("courseoverview", function() { 
  return {    
    restrict : 'A',    
    replace: true, 
    /*scope: {
        index: '@'
    },*/        
    transclude: true,      
    templateUrl: "views/course-overview.html",
    link: function link(scope, element, attrs) {
        scope.switched = false;
        //hover handler
        scope.hoverItem = function(hovered){
            if (hovered) {
                element.addClass('hover');
                $('#course-0 figure').addClass('tint')
            }
            else
                element.removeClass('hover');
        };
    }  
}});

Це потрібно $('#course-0 figure').addClass('tint')змінити пункт, що викликає.

Відповіді:


147

Загалом, я повністю погоджуюсь із використанням Джейсоном селектора css, але в деяких випадках ви можете не захотіти змінювати css, наприклад, коли використовуєте сторонній шаблон css, а волієте додавати / видаляти клас у елементі.

Наступний зразок демонструє простий спосіб додавання / видалення класу на ng-mouseenter / mouseleave:

<div ng-app>
  <div 
    class="italic" 
    ng-class="{red: hover}"
    ng-init="hover = false"
    ng-mouseenter="hover = true"
    ng-mouseleave="hover = false">
      Test 1 2 3.
  </div>
</div>

з деяким стилем:

.red {
  background-color: red;
}

.italic {
  font-style: italic;
  color: black;
}

Дивіться приклад запуску тут: зразок jsfiddle

Стиль наведення при наведенні викликає загрозу. Незважаючи на те, що наведене вище рішення встановлює властивість "наведення" у поточній області застосування, контролеру не потрібно це турбувати.


4
Обмеження: hoverзмінна сфери має бути однозначно названа, що не завжди є тривіальним, особливо для ng-repeated-елементів.
Аарон Кемпбелл,

1
@AaronCampbell: Кожен повторюваний об'єкт, створений ng-repeat, живе у своєму власному масштабі. Отже, поки ви ініціюєте змінну наведення елемента, область змінної є індивідуальною для кожного об’єкта. (я відредагував наведений вище приклад, щоб включити його).
Бас Гуссен,

39

У минулому я стикався з проблемами з IE та селектором css: hover, тому підхід, який я застосував, полягає у використанні спеціальної директиви.

.directive('hoverClass', function () {
    return {
        restrict: 'A',
        scope: {
            hoverClass: '@'
        },
        link: function (scope, element) {
            element.on('mouseenter', function() {
                element.addClass(scope.hoverClass);
            });
            element.on('mouseleave', function() {
                element.removeClass(scope.hoverClass);
            });
        }
    };
})

тоді на сам елемент ви можете додати директиву з назвами класів, які потрібно активувати, коли миша знаходиться над елементом, наприклад:

<li data-ng-repeat="item in social" hover-class="hover tint" class="social-{{item.name}}" ng-mouseover="hoverItem(true);" ng-mouseout="hoverItem(false);"
                index="{{$index}}"><i class="{{item.icon}}"
                box="course-{{$index}}"></i></li>

Це повинно додати клас наведення та відтінок, коли миша знаходиться над елементом і не ризикує зіткнення імені змінної області дії. Я не тестував, але події mouseenter та mouseleave все одно повинні перетворюватися на міститься елемент, що містить, тому в даному сценарії наступне все одно має працювати

<div hover-class="hover" data-courseoverview data-ng-repeat="course in courses | orderBy:sortOrder | filter:search"
 data-ng-controller ="CourseItemController"
 data-ng-class="{ selected: isSelected }">

звичайно передбачаючи, що лі - це фактичні діти батьківського div


Обмеження: це рішення не дозволяє додатково обумовлювати клас наведення; наприклад, ви не можете цього зробити ng-class="{active: isHovering && myBool}".
Аарон Кемпбелл,

1
^ Це обмеження може бути вирішена за допомогою виразу AngularJS для імені класу , який вирішує на рядок (або з {{}}або шляхом зміни hoverClass: '@'в '='або '&'). Наприклад:hover-class="{{ myBool ? 'active' : '' }}"
Аарон Кемпбелл

1
Мені знадобилося щось подібне і опублікував це на npm npmjs.com/package/hover-class
ryanve

15

Це моє рішення для мого сценарію:

<div class="btn-group btn-group-justified">
    <a class="btn btn-default" ng-class="{'btn-success': hover.left, 'btn-danger': hover.right}" ng-click="setMatch(-1)" role="button" ng-mouseenter="hover.left = true;" ng-mouseleave="hover.left = false;">
        <i class="fa fa-thumbs-o-up fa-5x pull-left" ng-class="{'fa-rotate-90': !hover.left && !hover.right, 'fa-flip-vertical': hover.right}"></i>
        {{ song.name }}
    </a>
    <a class="btn btn-default" ng-class="{'btn-success': hover.right, 'btn-danger': hover.left}" ng-click="setMatch(1)" role="button" ng-mouseenter="hover.right = true;" ng-mouseleave="hover.right = false;">
        <i class="fa fa-thumbs-o-up fa-5x pull-right" ng-class="{'fa-rotate-270': !hover.left && !hover.right, 'fa-flip-vertical': hover.left}"></i>
        {{ match.name }}
    </a>
</div>

стан за замовчуванням: введіть тут опис зображення

при наведенні курсору: введіть тут опис зображення


7

Думаю, було б набагато простіше поставити anchorтег i. Ви можете просто скористатися :hoverселектором css . Менше рухомих частин полегшує обслуговування, а менше завантаження javascript робить сторінку швидшою.

Це зробить фокус:

<style>
 a.icon-link:hover {
   background-color: pink;
 }
</style>

<a href="#" class="icon-link" id="course-0"><i class="icon-thumbsup"></id></a>

Приклад jsfiddle


Вибачте, це не те, що я шукаю. В основному у мене є список елементів, які створені в моєму першому ng-повторенні за допомогою директиви для їх відображення. У цій директиві є інший hg-repeat за допомогою іншої директиви, я хочу додати клас для конкретного елемента з першого циклу
Роб Паддок

ви можете використовувати ng-classдля динамічного присвоєння класу елементу - docs.angularjs.org/api/ng.directive:ngClass , або, ви можете використовувати звичайний classатрибут.
Джейсон

голосування проти, тому що це не вміст javascript. Однак підхід є дійсним, але найкращим буде як коментар.
JGallardo
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.