web-dev-qa-db-fra.com

Changer de classe au passage de la souris dans la directive

J'ai du mal à trouver un moyen de modifier une directive imbriquée dans une classe.

C'est le ng-repeat extérieur

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

Ci-dessous, le ng-repeat interne qui utilise une autre directive

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

Voici la directive appelant pour l'événement 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');
        };
    }  
}});

Ceci nécessite $('#course-0 figure').addClass('tint') pour modifier l'élément appelant.

78
Rob Paddock

En général, je suis tout à fait d’accord avec l’utilisation du sélecteur css par Jason, mais dans certains cas, vous pouvez ne pas vouloir changer le css, par exemple. lors de l'utilisation d'un css-template tiers, préférez plutôt ajouter/supprimer une classe sur l'élément.

L'exemple suivant montre un moyen simple d'ajouter/de supprimer une classe sur 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>

avec un peu de style:

.red {
  background-color: red;
}

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

Voir l'exemple en cours ici: exemple de jsfiddle

Le style en vol stationnaire est une préoccupation de vue. Bien que la solution ci-dessus définisse une propriété "survol" dans l'étendue actuelle, le contrôleur n'a pas à s'en préoccuper.

148
Bjørn Egil

J'ai rencontré des problèmes dans le passé avec IE et le sélecteur css: hover), de sorte que l'approche que j'ai adoptée consiste à utiliser une directive personnalisée.

.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);
            });
        }
    };
})

puis sur l'élément lui-même, vous pouvez ajouter la directive avec les noms de classe que vous souhaitez activer lorsque la souris est sur l'élément, par exemple:

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

Cela devrait ajouter le survol et la teinte de la classe lorsque la souris survole l'élément et ne risque pas de collision avec le nom de la variable de portée. Je n'ai pas encore testé, mais les événements mouseenter et mouseleave doivent toujours s'afficher jusqu'à l'élément conteneur. Dans ce scénario, les opérations suivantes devraient toujours fonctionner.

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

à condition bien sûr que les li soient en fait des enfants du parent div

39
Warrenn enslin

Ceci est ma solution pour mon scénario:

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

état par défaut: enter image description here

en vol stationnaire: enter image description here

15
Tjorriemorrie

Je pense qu'il serait beaucoup plus facile de mettre une balise anchor autour de i. Vous pouvez simplement utiliser le css :hover sélecteur. Moins de pièces mobiles facilite la maintenance, et moins de JavaScript à charger rend la page plus rapide.

Ça fera l'affaire:

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

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

exemple jsfiddle

8
Jason