tim
tim

Reputation: 3903

Do something when dynamic element is created

Via a click event, I injected an element with a custom attribute
<div class="added" myValue="hello"></div> to the DOM.

I wrote a generic function:

$('.added').each(function(){
    console.log( $(this).attr('myValue') );
});

Doesn't work. I thought $.each() can handle dynamic elements?

UPDATE to the question:

I realize using .each() is the wrong approach. But what to do if I don't want to attach an event handler to the element. I just want to automatically do stuff to any elements of a certain class name, regardless of when they've been added to the DOM. Seems like a common use case.

Upvotes: 0

Views: 301

Answers (4)

Kevin B
Kevin B

Reputation: 95024

When your click event happens, do your "something" there.

$("#someelemt").click(function(){
    var el = $("<div class='added' myValue='hello'></div>").appendTo("#someotherelement");
    console.log(el.attr("myValue")); // <--- something
});

ID's must be unique, so i changed added to a class.

If you want to separate the two, have your click event trigger an event, then use event delegation to listen for it.

$("#someelemt").click(function(){
    var el = $("<div class='added' myValue='hello'></div>").appendTo("#someotherelement");
    el.trigger("added");
});
$(document).on("added","div",function(){
    console.log(this.getAttribute("myValue")); // <--- something
});

$.each does not work with future elements, only the elements that exist when the code is executed.

Update for question Update
That simply isn't possible without writing inefficient code. It would require either using DOMMutationEvents which can be inefficient, are depreciated, and are not supported in all browsers, or you can use a setInterval which is also inefficient because it would be constantly running searching the dom for new elements.

Upvotes: 1

gdoron
gdoron

Reputation: 150253

  • No, each doesn't handle dynamic added elements, it only apply to the element that existed in the DOM when the jQuery object created(or modified).
  • .each function on id selector doesn't make any sense as id should be unique in the DOM. I suggest reading this: jQuery id selector works only for the first element

You must call each after you inject the element, or use delegate event, like on with selector.

Upvotes: 4

Explosion Pills
Explosion Pills

Reputation: 191729

You can't use the same id attribute on multiple elements. You need different IDs each time. The ID selector # will only select the first of all of those elements, which is why it doesn't appear to be looping.

Although you really should change the ids of the other elements, this will actually still work:

$("[id=added]").each(...

Upvotes: 0

Darin Dimitrov
Darin Dimitrov

Reputation: 1038730

$.each() will loop through the elements that are matching your selector at the moment you are calling this method. So if you call this method before adding the elements to the DOM dynamically you cannot possibly expect that this method will return you some elements that you might hypothetically add to the DOM at some future event.

So simply call the $.each() function after you have added the elements to the DOM.

Also there seems to be an inconsistency in your code. You are using an id selector $('#added') which can only return a single element. Yes, ids must be unique through the entire DOM. So calling .each() on a single element hardly makes any sense unless you have some broken HTML.

Upvotes: 3

Related Questions