Is there a JavaScript / jQuery DOM change listener?

In essence, I want to execute scripts when the content of DIV changes. Because scripts are separate (content scripts in Chrome extensions and web scripts), I need a way to simply watch the DOM state change. I can set up polling, but it seems sloppy.

#1 building

The other method depends on how you change the Div. If you use JQuery's html () method to change the contents of a div, you can extend the method and call the registration function every time you put html into a Div.

(function( $, oldHtmlMethod ){
    // Override the core html method in the jQuery object.
    $.fn.html = function(){
        // Execute the original HTML method using the
        // augmented arguments collection.

        var results = oldHtmlMethod.apply( this, arguments );
        com.invisibility.elements.findAndRegisterElements(this);
        return results;

    };
})( jQuery, jQuery.fn.html );

We just intercept the call to html () and call a registration function. In the context, it means that the target element gets the new content, and then passes the call to the original jquery.html () function. Remember to return the results of the original html () method, because JQuery wants to use it for method linking.

For more information about method overrides and extensions, visit http://www.bennadel.com/blog/2009-Using-Self-Executing-Function-Arguments-To-Override-Core-jQuery-Methods.htm , which I named the closure function crisp. You can also view plug-in tutorials on the JQuery site.

#2 building

A few years later, a better solution is now officially available. DOM4 mutation observer Instead of the deprecated DOM3 mutation event. At present, they In modern browsers The implementation is based on the mutionobserver (or webkitmutionobserver as the supplier prefix in the old version of Chrome):

MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

var observer = new MutationObserver(function(mutations, observer) {
    // fired when a mutation occurs
    console.log(mutations, observer);
    // ...
});

// define what element should be observed by the observer
// and what types of mutations trigger the callback
observer.observe(document, {
  subtree: true,
  attributes: true
  //...
});

This example listens for DOM changes on a document and its entire subtree, and will trigger when element properties and structure changes. The draft specification contains valid Variation listener properties Complete list of:

childList

  • Set to true if you want to observe mutations in the target child.

attribute

  • Set to true if you want to observe a variation of the target attribute.

characterData

  • Set to true if you want to observe a variation of the target data.

subtree

  • If you want to observe not only the target, but also the descendants of the target, set it to true.

attributeOldValue

  • Set to true. If attributes is set to true, the attribute value of the target will be recorded before the mutation.

characterDataOldValue

  • Set to true, if characterData is set to true and the target's data will be recorded before the mutation.

attributeFilter

  • If you do not need to observe all property mutations, set to a list of property local names (no namespace).

(this list is the latest information as of April 2014; you can check for any changes in the specifications.)

#3 building

edit

This answer is not supported at this time. see a worm The answer.

Because this is for the Chrome extension, you'd better use the standard DOM event DOMSubtreeModified. See cross browser for this Event Support for. Chrome has supported this feature since 1.0.

$("#someDiv").bind("DOMSubtreeModified", function() {
    alert("tree changed");
});

Ad locum See the working example.

#4 building

except MutationObserver API In addition to the "primitive" tools provided, there are "handy" libraries for dealing with DOM mutations.

Consider: MutationObserver represents each DOM change in a subtree. So, for example, if you are waiting for an element to be inserted, the element might be inside a child element of transitions. Mutation [i]. Addednodes [J].

Another problem is when your own code changes the DOM in response to a mutation - you usually want to filter it out.

A good convenient library for solving such problems is“ mutation-summary (Disclaimer: I'm not the author, just a satisfied user), which enables you to specify a query for the content you are interested in and get the content accurately.

Basic usage examples in documents:

var observer = new MutationSummary({
  callback: updateWidgets,
  queries: [{
    element: '[data-widget]'
  }]
});

function updateWidgets(summaries) {
  var widgetSummary = summaries[0];
  widgetSummary.added.forEach(buildNewWidget);
  widgetSummary.removed.forEach(cleanupExistingWidget);
}

#5 building

Many sites use AJAX to dynamically add / display / change content. Sometimes, it is used instead of live navigation, so in this case, the current URL changes programmatically, and the content script is not automatically executed by the browser because the page cannot be obtained completely from the remote server.

In content script Common JS methods are available to detect page changes.

  • MutationObserver ( docs )To detect DOM changes literally:

  • Event listeners for sites signaling content changes by sending DOM events:

  • Check DOM regularly through setInterval:
    Obviously, this method works only when you wait for a specific element identified by its ID / selector to appear, and unless you invent a way to fingerprint existing content, it won't allow you to generally detect new content that is added dynamically.

  • stay DOM script injected Hidden inside History API :

    document.head.appendChild(document.createElement('script')).text = '(' + function() { // injected DOM script is not a content script anymore, // it can modify objects and functions of the page var _pushState = history.pushState; history.pushState = function(state, title, url) { _pushState.call(this, state, title, url); window.dispatchEvent(new CustomEvent('state-changed', {detail: state})); }; // repeat the above for replaceState too } + ')(); this.remove();'; // remove the DOM script element // And here content script listens to our DOM script custom events window.addEventListener('state-changed', function(e) { console.log('History state changed', e.detail, location.hash); doSomething(); });
  • hear hashchange and popstate Event:

    window.addEventListener('hashchange', function(e) { console.log('URL hash changed', e); doSomething(); }); window.addEventListener('popstate', function(e) { console.log('State changed', e); doSomething(); });


Extension specific: detection Backstage / In the event page URL changes.

There are some advanced API s for navigation: webNavigationwebRequest , but we will use the simple chrome.tabs.onUpdated Event listener, This message sends the message To content script:

  • manifest.json:
    statement Background / event page
    statement Content script
    Add "tabs" Jurisdiction .

  • background.js

    var rxLookfor = /^https?:\\/\\/(www\\.)?google\\.(com|\\w\\w(\\.\\w\\w)?)\\/.*?[?#&]q=/; chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { if (rxLookfor.test(changeInfo.url)) { chrome.tabs.sendMessage(tabId, 'url-update'); } });
  • content.js

    chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) { if (msg === 'url-update') { doSomething(); } });

Tags: JQuery Attribute Google github

Posted on Thu, 13 Feb 2020 04:27:25 -0800 by DjNaF