Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect new element creation in jQuery?

Lets say I have the following code that returns number of anchor elements on a page:

function getLinkCount() {
    alert("Links:" + $("a").length);
}

If I call in on document ready it would work as expected. But what if now a new link gets inserted into a page dynamically through Javascript, how can I get notified to run link counter function again? (I have no control over a script that could create a new link).

Basically I am looking for something similar to live() only that would be watching element creation event, something like:

$("a").live("create", getLinkCount);

that would trigger when a new element is created.

like image 416
serg Avatar asked Aug 02 '10 01:08

serg


4 Answers

You could use the DOMSubtreeModified event. For example:

$(document).bind('DOMSubtreeModified',function(){
  console.log("now there are " + $('a').length + " links on this page.");
})
like image 126
mattsh Avatar answered Nov 12 '22 12:11

mattsh


You can use the .livequery() plugin for this, it runs for each element, including new ones, like this:

$("a").livequery(getLinkCount);

However, this plugin is out-of-date and is not recommended for current versions of jQuery.

It's usually easier to do this when you create the elements though, for example if you're doing it after AJAX requests, the .ajaxComplete() handler may be a good place, for example:

$(document).ajaxComplete(getLinkCount);

This would run after each request, and since you normally create elements in your success handler, they would already be present when this complete handler runs.

like image 29
Nick Craver Avatar answered Nov 12 '22 12:11

Nick Craver


You can use the arrive.js library that I developed for the exact same purpose (it uses MutationObserver internally). Usage:

document.arrive('a', function(){
    // 'this' refers to the newly created element
    var newElem = this;
});
like image 7
Uzair Farooq Avatar answered Nov 12 '22 11:11

Uzair Farooq


The accepted answer is from 2010 and uses a jQuery plugin that is no longer being actively maintained. The highest upvoted answer suggests using DOMSubTreeModified which is now deprecated and should no longer be used.

Today, a MutationObserver is what you should use to detect when an element has been added to the DOM. MutationObservers are now widely supported across all modern browsers (Chrome 26+, Firefox 14+, IE11, Edge, Opera 15+, etc).

Here's a simple example of how you can use a MutationObserver to listen for when an element is added to the DOM.

For brevity, I'm using jQuery syntax to build the node and insert it into the DOM.

var myElement = $("<div>hello world</div>")[0];

var observer = new MutationObserver(function(mutations) {
   if (document.contains(myElement)) {
        console.log("It's in the DOM!");
        observer.disconnect();
    }
});

observer.observe(document, {attributes: false, childList: true, characterData: false, subtree:true});

$("body").append(myElement); // console.log: It's in the DOM!

The observer event handler will trigger whenever any node is added or removed from the document. Inside the handler, we then perform a contains check to determine if myElement is now in the document.

You don't need to iterate over each MutationRecord stored in mutations because you can perform the document.contains check directly upon myElement.

To improve performance, replace document with the specific element that will contain myElement in the DOM.

like image 6
Elliot B. Avatar answered Nov 12 '22 12:11

Elliot B.