Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
556 views
in Technique[技术] by (71.8m points)

jquery - Watching for DOM changes, the elegant way

I need to watch for an attribute change on any of the children of a specific DOM element. So far, I have been using mutation events.

The problem was - they were buggy: e.g. under Chromium, DOMAttrModified was not fired but DOMSubtreeModified was. The problem was easy to solve: because according to the specification, DOMSubtreeModified is fired if any of the other events is fired, so I just listened to DOMSubtreeModified.

Anyway, Chromium, in the recent versions, stopped firing anything if an attribute has been modified.

The new Mutation Observer API, however, works flawlessly.

Until now, I only need to fire a callback upon ANY change of the subtree of a specific element - simply because nothing else is supposed to change - so I solved my problem by just using mutation events & mutation observer (when available) in the same piece of code.

However, now I need to do more powerful filtering of the events (e.g. on new node, on removed node) - so is there a library, possibly a jQuery plug-in, that would allow me to elegantly use both of these APIs - MutationObserver if available and mutation events as a fallback, with the ability to filter for specific event types (e.g. element added, attribute changed).

E.g.

$("#test").watch({onNewElement: 1}, function(newElement){})
$("#test").watch({onNewAttribute: 1}, function(modifiedElement) {})

Or without jQuery

watchChanges("#test", {onNewElement: 1}, function(newElement){})
watchChanges("#test", {onNewAttribute: 1}, function(modifiedElement){})
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Would this work?

http://darcyclarke.me/development/detect-attribute-changes-with-jquery/

$.fn.watch = function(props, callback, timeout){
    if(!timeout)
        timeout = 10;
    return this.each(function(){
        var el      = $(this),
            func    = function(){ __check.call(this, el) },
            data    = { props:  props.split(","),
                        func:   callback,
                        vals:   [] };
        $.each(data.props, function(i) { data.vals[i] = el.css(data.props[i]); });
        el.data(data);
        if (typeof (this.onpropertychange) == "object"){
            el.bind("propertychange", callback);
        } else if ($.browser.mozilla){
            el.bind("DOMAttrModified", callback);
        } else {
            setInterval(func, timeout);
        }
    });
    function __check(el) {
        var data    = el.data(),
            changed = false,
            temp    = "";
        for(var i=0;i < data.props.length; i++) {
            temp = el.css(data.props[i]);
            if(data.vals[i] != temp){
                data.vals[i] = temp;
                changed = true;
                break;
            }
        }
        if(changed && data.func) {
            data.func.call(el, data);
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...