Can jQuery selectors be used with DOM mutation observers?

后端 未结 4 1247
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-04 10:23

HTML5 includes a concept of \"mutation observers\" to monitor changes to the browser\'s DOM.

Your observer callback will be passed data which looks a lot like DOM tr

相关标签:
4条回答
  • 2020-12-04 10:36

    I know this is an old question but perhaps this can help others searching for alternative solutions. I recently learned about Mutation Observers and wanted to experiment with using them alongside jQuery. I came up with two possible approaches and turned them into plugins. The code is available here.

    The first approach (jquery.observeWithEvents.js) uses jQuery's trigger() function to trigger either an insertNode or removeNode event which can be bound to via jQuery's on() function. The second approach (jquery.observeWithCallbacks.js) uses traditional callback parameters. Please take a look at the README for examples and usage.

    0 讨论(0)
  • 2020-12-04 10:37

    I don't have any personal code snippets for this one, but I have three resources that may help:

    • Mutabor Github Repository
    • Article + JQuery Utility for Mutators
    • "jquery-mutation-summary" - extension of mutation-summary ( probably the best out of these three )

    Example from link #3 'jquery-mutation-summary' library:

    // Use document to listen to all events on the page (you might want to be more specific)
    var $observerSummaryRoot = $(document);
    
    // Simplest callback, just logging to the console
    function callback(summaries){
        console.log(summaries);
    }
    
    // Connect mutation-summary
    $observerSummaryRoot.mutationSummary("connect", callback, [{ all: true }]);
    
    // Do something to trigger mutationSummary
    $("<a />", { href: "http://joelpurra.github.com/jquery-mutation-summary"}).text("Go to the jquery-mutation-summary website").appendTo("body");
    
    // Disconnect when done listening
    $observerSummaryRoot.mutationSummary("disconnect");
    
    0 讨论(0)
  • 2020-12-04 11:00

    Yes, you can use jQuery selectors on data returned to mutation observer callbacks.

    See this jsFiddle.

    Suppose you had HTML like so:

    <span class="myclass">
        <span class="myclass2">My <span class="boldly">vastly</span> improved</span>
        text.
    </span>
    


    And you set an observer, like so:

    var targetNodes         = $(".myclass");
    var MutationObserver    = window.MutationObserver || window.WebKitMutationObserver;
    var myObserver          = new MutationObserver (mutationHandler);
    var obsConfig           = { childList: true, characterData: true, attributes: true, subtree: true };
    
    //--- Add a target node to the observer. Can only add one node at a time.
    targetNodes.each ( function () {
        myObserver.observe (this, obsConfig);
    } );
    
    function mutationHandler (mutationRecords) {
        console.info ("mutationHandler:");
    
        mutationRecords.forEach ( function (mutation) {
            console.log (mutation.type);
    
            if (typeof mutation.removedNodes == "object") {
                var jq = $(mutation.removedNodes);
                console.log (jq);
                console.log (jq.is("span.myclass2"));
                console.log (jq.find("span") );
            }
        } );
    }
    

    You'll note that we can jQuery on the mutation.removedNodes.


    If you then run $(".myclass").html ("[censored!]"); from the console you will get this from Chrome and Firefox:

    mutationHandler:
    childList
    jQuery(<TextNode textContent="\n ">, span.myclass2, <TextNode textContent="\n text.\n ">)
    true
    jQuery(span.boldly)
    

    which shows that you can use normal jQuery selection methods on the returned node sets.

    0 讨论(0)
  • 2020-12-04 11:03

    I was working on a very similar problem for a Stack Exchange script I'm working on, and I needed to be able to monitor the DOM for changes. The jQuery docs didn't have anything helpful, but I did discover that the DOMNodeInserted event works in Chrome:

    document.addEventListener("DOMNodeInserted", function(event){
        var element = event.target;
    
        if (element.tagName == 'DIV') {
            if (element.id == 'seContainerInbox') {
                //alert($('#seContainerInbox').parent().get(0).tagName);
                trimStoredItems();
                $('#seTabInbox').click();
                //   var newCount = getNewCount();
                // if there are new inbox items, store them for later
                storeNewInboxItems();
                applyNewStyleToItems();
            }
        }
    });
    

    I'm not 100% sure if this works in Firefox as I haven't got that far yet in the development process. Hope this helps!

    0 讨论(0)
提交回复
热议问题