Ändern Sie die Klasse beim Mouseover in der Direktive


77

Ich habe Probleme damit, eine Klasse dazu zu bringen, eine verschachtelte Direktive zu ändern.

Dies ist die äußere ng-Wiederholung

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

Unten ist die innere ng-Wiederholung, die eine andere Direktive verwendet

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

Hier ist die Anweisung, die das Schwebeereignis fordert

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

Dies muss $('#course-0 figure').addClass('tint')das aufrufende Element ändern.

Antworten:


147

Im Allgemeinen stimme ich Jasons Verwendung des CSS-Selektors voll und ganz zu, aber in einigen Fällen möchten Sie das CSS möglicherweise nicht ändern, z. B. wenn Sie eine CSS-Vorlage eines Drittanbieters verwenden, und ziehen es vor, eine Klasse für das Element hinzuzufügen / zu entfernen.

Das folgende Beispiel zeigt eine einfache Möglichkeit zum Hinzufügen / Entfernen einer Klasse in 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>

mit etwas Styling:

.red {
  background-color: red;
}

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

Siehe laufendes Beispiel hier: jsfiddle sample

Das Styling beim Schweben ist ein Anliegen. Obwohl die obige Lösung eine "Hover" -Eigenschaft im aktuellen Bereich festlegt, muss sich der Controller darüber keine Gedanken machen.


4
Einschränkung: Die hoverBereichsvariable muss eindeutig benannt werden, was insbesondere bei ng-repeated-Elementen nicht immer trivial ist .
Aaron Campbell

1
@AaronCampbell: Jedes wiederholte Objekt, das durch ng-repeat erstellt wurde, lebt in seinem eigenen Bereich. Solange Sie die Hover-Variable für das Element initiieren, ist der Variablenbereich für jedes Objekt individuell. (Ich habe das obige Beispiel bearbeitet, um dies einzuschließen).
Bas Goossen

39

Ich habe in der Vergangenheit Probleme mit dem IE und dem css: hover-Selektor gehabt, daher habe ich die Verwendung einer benutzerdefinierten Direktive gewählt.

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

Anschließend können Sie auf dem Element selbst die Direktive mit den Klassennamen hinzufügen, die aktiviert werden sollen, wenn sich die Maus über dem Element befindet. Beispiel:

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

Dies sollte den Klassenhover und den Farbton hinzufügen, wenn sich die Maus über dem Element befindet und nicht das Risiko einer Kollision mit dem Namen des Bereichsvariablen besteht. Ich habe nicht getestet, aber die Ereignisse mouseenter und mouseleave sollten immer noch bis zum enthaltenden Element sprudeln, sodass im angegebenen Szenario das Folgende weiterhin funktionieren sollte

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

vorausgesetzt natürlich, dass die li's infakte Kinder des Eltern-Div sind


Einschränkung: Mit dieser Lösung kann die Schwebeklasse nicht weiter konditioniert werden. zB kannst du nicht tun ng-class="{active: isHovering && myBool}".
Aaron Campbell

1
^ Diese Einschränkung kann durch Verwendung eines AngularJS-Ausdrucks für den Klassennamen behoben werden, der in eine Zeichenfolge aufgelöst wird (entweder mit {{}}oder durch Ändern hoverClass: '@'in '='oder '&'). Zum Beispiel:hover-class="{{ myBool ? 'active' : '' }}"
Aaron Campbell

1
Ich brauchte etwas Ähnliches und veröffentlichte es auf npm npmjs.com/package/hover-class
ryanve

15

Dies ist meine Lösung für mein Szenario:

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

Standardzustand: Geben Sie hier die Bildbeschreibung ein

beim Schweben: Geben Sie hier die Bildbeschreibung ein


7

Ich denke, es wäre viel einfacher, ein anchorEtikett zu platzieren i. Sie können einfach den CSS- :hoverSelektor verwenden. Weniger bewegliche Teile erleichtern die Wartung und weniger zu ladendes Javascript beschleunigt die Seite.

Dies wird den Trick machen:

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

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

jsfiddle Beispiel


Entschuldigung, das ist nicht das, wonach ich suche. Grundsätzlich habe ich eine Liste von Elementen, die in meiner ersten ng-Wiederholung mit einer Direktive erstellt wurden, um sie anzuzeigen. In dieser Direktive gibt es eine weitere hg-Wiederholung mit einer anderen Direktive. Ich möchte eine Klasse für das spezifische Element aus der ersten Schleife hinzufügen
Rob Paddock

Sie können verwenden ng-class, um einem Element dynamisch eine Klasse zuzuweisen - docs.angularjs.org/api/ng.directive:ngClass , oder Sie können ein reguläres classAttribut verwenden.
Jason

Abstimmen, weil es nicht in Javascript-Inhalt ist. Der Ansatz ist jedoch gültig, wäre aber am besten als Kommentar.
JGallardo
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.