2016-04-04 4 views
0

Das Ziel ist, dass, wenn ein Element nahe an den Anfang einer Seite kommt, wendet es eine Klasse auf ein Nav-Element.AngularJS - Direktive nur feuern auf eine von vielen Verwendungen

TEMPLATE

<ul class="nav"> 
    <li> 
    <a href="#someID">Some ID</a> 
    </li> 
</ul> 
... 

<div id="someId" hightlight-relevant-items></div> 

RICHTLINIE

'use strict'; 

angular.module("common.directives") 
    .directive('highlightRelevantItems', function() { 
     return function (scope, element, attrs) { 

      scope.detectPos = function() { 
       var distanceScrolled = $(window).scrollTop(); 

       var topOfElement = element.offset().top; 
       var height = element.height(); 
       var link = '[href="#' + element.attr('id') + '"]'; 
       var delta = topOfElement - distanceScrolled; 
       var offScreen = delta+height 

       if (delta < 0 && offScreen > 0) { 
        $(link).addClass('active'); 
       } else if (delta >= 0) { 
        $(link).removeClass('active'); 
       } else if (offScreen <= 0) { 
        $(link).removeClass('active'); 
       } 
       console.log(element.attr('id') + ' ' + topOfElement); 

      } 

      $(window).bind('scroll', function() { 

       scope.detectPos(); 
      }); 

     } 
    }); 

Gerade jetzt, diese Richtlinie Feuer für alle Elemente der Richtlinie Attribut, sondern nur auf den letzten interation registriert. Also, wenn ich someID1, someID2, someID3 hatte, wird es für alle Elemente ausgelöst, aber nur mit Daten für someID3.

Wie bekomme ich es für alle Elemente mit der Richtlinie arbeiten?

Antwort

1

Sie benötigen einen isolierten Raum für jede Instanz der Richtlinie. Wie folgt aus:

angular.module("common.directives") 
 
    .directive('highlightRelevantItems', function() { 
 

 
     return { 
 
      scope: { 
 
      detectPos: '&' 
 
      }, 
 
      link: function(scope, element, attrs) { 
 

 
      scope.detectPos = function() { 
 
       var distanceScrolled = $(window).scrollTop(); 
 

 
       var topOfElement = element.offset().top; 
 
       var height = element.height(); 
 
       var link = '[href="#' + element.attr('id') + '"]'; 
 
       var delta = topOfElement - distanceScrolled; 
 
       var offScreen = delta + height 
 

 
       if (delta < 0 && offScreen > 0) { 
 
        $(link).addClass('active'); 
 
       } else if (delta >= 0) { 
 
        $(link).removeClass('active'); 
 
       } else if (offScreen <= 0) { 
 
        $(link).removeClass('active'); 
 
       } 
 
       console.log(element.attr('id') + ' ' + topOfElement); 
 

 
      } 
 

 
      $(window).bind('scroll', function() { 
 

 
       scope.detectPos(); 
 
      }); 
 

 
      } 
 
     } 
 
    });

+0

Ich hatte mir diese Methode angeschaut, konnte aber nicht herausfinden, wohin ich meine Fensterrolle legen musste. Danke vielmals. – Plummer

+0

Erstellen Sie eine separate Direktive dafür und verwenden Sie die Direktive im Body-Tag oder einem Root-Div-Tag, da es nur einmal ausgelöst werden sollte – dannielum

1

Ihre Anweisung verwendet den Bereich des übergeordneten Elements. Das bedeutet, dass Sie bei jeder Initialisierung der Direktivescope.detectPos überschreiben. Deshalb wird es nur für das letzte Element someID3 aufgerufen.

wäre eine schnelle Lösung sein nicht detectPos an Umfang zu binden und es nur als Funktion erklären:

angular 
    .module('common.directives') 
    .directive('highlightRelevantItems', function() { 
    return function(scope, element, attrs) { 

     var detectPos = function() { 
     var distanceScrolled = $(window).scrollTop(); 

     var topOfElement = element.offset().top; 
     var height = element.height(); 
     var link = '[href="#' + element.attr('id') + '"]'; 
     var delta = topOfElement - distanceScrolled; 
     var offScreen = delta + height 

     if (delta < 0 && offScreen > 0) { 
      $(link).addClass('active'); 
     } else if (delta >= 0) { 
      $(link).removeClass('active'); 
     } else if (offScreen <= 0) { 
      $(link).removeClass('active'); 
     } 

     console.log(element.attr('id') + ' ' + topOfElement); 
     } 

     $(window).bind('scroll', function() { 
     detectPos(); 
     }); 
    } 
    }); 
+0

Ich habe versucht zu tun 'dir = dies,' aber es kam wieder 'ctrl' ist nicht definiert. Ist meine Syntax falsch? – Plummer

+0

Ich verstehe nicht, was Sie sagen ... Ich habe auch ein Codebeispiel beigefügt. –

Verwandte Themen