最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angularjs directives updating to changes in DOM attribute values - Stack Overflow

programmeradmin4浏览0评论

I've been working on a scrollspy module for Angularjs. I've run into the problem where if the page is dealing with dynamic content, the scrollspy data (element positions) quickly bees outdated. What is the angularjs way of dealing with issues such as this?

Should any directive that performs DOM manipulation $broadcast an event that the scrollspy module looks out for - allowing it to refactor its position data?

Should the scrollspy module check every x seconds for a change in scrollHeight with $timeout?

Or even better, is there a way to bind and watch for DOM attribute value changes (attributes such as offsetTop, offsetHeight, scrollHeight, not data attributes)?

Update: Added code base to GitHub

I've been working on a scrollspy module for Angularjs. I've run into the problem where if the page is dealing with dynamic content, the scrollspy data (element positions) quickly bees outdated. What is the angularjs way of dealing with issues such as this?

Should any directive that performs DOM manipulation $broadcast an event that the scrollspy module looks out for - allowing it to refactor its position data?

Should the scrollspy module check every x seconds for a change in scrollHeight with $timeout?

Or even better, is there a way to bind and watch for DOM attribute value changes (attributes such as offsetTop, offsetHeight, scrollHeight, not data attributes)?

Update: Added code base to GitHub

Share Improve this question edited Nov 24, 2013 at 12:56 Patrick asked Oct 13, 2013 at 16:17 PatrickPatrick 3,4981 gold badge38 silver badges64 bronze badges 2
  • Constraining other directives to emit events would likely bee unwieldy quickly and certainly make your module unfriendly to work with. There isn't an event for changes to the dim of elements unfortunately, so I am afraid a polling $timeout impl is likely your best candidate. At least it is easily testable with $timeout.flush() :) – SonOfNun Commented Oct 14, 2013 at 6:56
  • Being the devils advocate here, but what if element heights changed, but the overall scrollHeight did not... Suddenly you need to be checking everything – Patrick Commented Oct 15, 2013 at 22:46
Add a ment  | 

3 Answers 3

Reset to default 6

Mutation Observers seem to be the facility needed, unfortunately they are 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);

}

Currently searching for a polyfill that actually works.

EDIT: Added polling as a fallback if Mutation Observers aren't supported.

Something like this should work... doesn't seem to update with CSS transitions though.

scope.$watch(function(){
    return elem[0].offsetLeft;
}, function(x){
    console.log('ITEM AT '+x);
});

Without the code I'm stabbing in the dark a bit, but I would suggest your scrollspy module check every time $rootScope receives a $digest call. So use $rootScope.$watch.

$rootScope.$watch(function() {
  // Update scrollspy data here
}
发布评论

评论列表(0)

  1. 暂无评论