在指令中将鼠标悬停时更改类


77

我在解决如何使类在嵌套指令上进行更改时遇到麻烦。

这是外部ng-repeat

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

这是指令im要求悬停事件

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')更改呼叫项。

Answers:


147

总的来说,我完全同意Jason使用css选择器,但是在某些情况下,您可能不想更改css,例如,当使用第三方css-template时,而是更喜欢在元素上添加/删除类。

以下示例显示了在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
限制:hoverscope变量必须唯一地命名,这并不总是琐碎的,尤其是在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。您可以只使用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示例


对不起,这不是即时消息。基本上,我有一个使用指令显示它们的第一个ng-repeat中产生的项目的列表。在该指令中,还有另一个hg-repeat使用另一个指令,我想在第一个循环的特定项上添加一个类
Rob Paddock

您可以ng-class用来动态地将类分配给元素-docs.angularjs.org/api/ng.directive:ngClass,也可以使用常规class属性。
杰森

投反对票,因为它不在javascript内容中。但是,该方法是有效的,但最好将其作为注释。
JGallardo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.