2013-10-13 8 views
6

Ich habe an einem Scrollspy-Modul für Angularjs gearbeitet. Ich bin auf das Problem gestoßen, wo, wenn die Seite mit dynamischem Inhalt beschäftigt ist, die scrollspy Daten (Elementpositionen) schnell veraltet werden. Wie ist der angulare Umgang mit solchen Fragen?Angularjs-Direktiven bei Änderungen an DOM-Attributwerten

Sollte irgendeine Direktive, die eine DOM-Manipulation durchführt, ein Ereignis sein, nach dem das scrollspy-Modul Ausschau hält - um seine Positionsdaten umzuformen?

Sollte das Scrollspy-Modul alle x Sekunden auf eine Änderung in scrollHeight mit $timeout überprüfen?

Oder noch besser, gibt es eine Möglichkeit zum Binden und Überwachen von DOM-Attributwertänderungen (Attribute wie offsetTop, offsetHeight, scrollHeight, nicht Datenattribute)?

Update: Added code base to GitHub

+0

Die Einschränkung anderer Richtlinien, Ereignisse auszulösen, würde wahrscheinlich schnell unhandlich werden und Ihr Modul unfreundlich machen. Es gibt leider kein Event für Änderungen an der Helligkeit der Elemente, daher befürchte ich, dass ein Polling $ timeout impl wahrscheinlich der beste Kandidat ist. Zumindest ist es leicht mit $ timeout.flush() zu testen. – SonOfNun

+0

Als Devil Advocates hier, aber was wäre, wenn Elementhöhen geändert würden, aber der gesamte 'scrollHeight' nicht ... Plötzlich musst du alles überprüfen – Patrick

Antwort

6

Mutation Beobachter scheinen die Anlage benötigt werden, leider sind sie only supported by the latest browsers.

var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; 
if(MutationObserver) { 

    for (var i = 0; i < spyService.spies.length; i++) { 
     var spy = spyService.spies[i].scope.spy; 
     var target = document.getElementById(spy); 

     var config = { 
      attributes: true, 
      childList: true, 
      characterData: true, 
      subtree: true 
     }; 
     var observer = new MutationObserver(function(mutations) { 
      mutations.forEach(function(mutation) { 
       console.warn('mutation observation'); 
      }); 
     }).observe(target, config); 
    } 
} 
else { 
    console.warn('no mutation observers here'); 
    $interval(function() { 
     angular.element(document).ready(function() { 
      console.log('refreshing'); 
     }); 
    }, 2000); 

} 

Derzeit auf der Suche nach einem Polyfill, das tatsächlich funktioniert.

BEARBEITEN: Abfrage wurde als Fallback hinzugefügt, wenn Mutationsbeobachter nicht unterstützt werden.

0

Ohne den Code, den ich im Dunkeln ein wenig stechend, aber ich würde Ihr scrollspy Modul Prüfung jedes Mal $rootScope erhält einen $digest Anruf vorschlagen. Verwenden Sie also $rootScope.$watch.

$rootScope.$watch(function() { 
    // Update scrollspy data here 
} 
+0

Entschuldigung, nahm mir etwas Zeit, um darauf zurückzukommen. Link zum Code auf GitHub hinzugefügt. Wird dies jedoch spät genug genannt, sobald das DOM aktualisiert und gerendert wurde? – Patrick

+0

Ja, es sollte erst aufgerufen werden, nachdem AngularJS die Anweisungen und Controller geladen und sie gebunden hat. –

+0

Ran in $ Digest Probleme, wahrscheinlich nur die aktuelle Code-Struktur jedoch. Leider kümmert sich das nur um die Hälfte des Problems (vorausgesetzt, es funktioniert). Ein 'div', der zum Beispiel seine Höhe beim Anklicken ändert, wird nicht abgefangen, es sei denn, es heißt auch 'scope. $ Apply();' Das ist im Grunde die gleiche Voraussetzung wie das Aufrufen einer re-calc-Methode ... – Patrick

1

So etwas sollte funktionieren ... scheint aber nicht mit CSS-Übergängen zu aktualisieren.

Verwandte Themen