Изменить класс при наведении указателя мыши в директиве

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

Это внешний нг-повтор

<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>

Вот директива, которую я призываю к событию hover

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') чтобы изменить вызывающий элемент.

Ответ 1

В общем, я полностью согласен с использованием Джейсоном селектора 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

Стайлинг при зависании - это серьезная проблема. Хотя решение выше устанавливает свойство hover в текущей области видимости, контроллер не должен беспокоиться об этом.

Ответ 2

В прошлом я столкнулся с проблемами с 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 }">

обеспечение, конечно, что li являются дочерними дочерними элементами родительского div

Ответ 3

Это мое решение для моего сценария:

<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>

Состояние по умолчанию: enter image description here

при наведении: enter image description here

Ответ 4

Я думаю, было бы гораздо проще разместить тег anchor вокруг i. Вы можете просто использовать селектор css :hover. Меньше движущихся частей упрощает техническое обслуживание, и меньше загрузок 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