Dennis Martinez
Dennis Martinez

Reputation: 6512

How can I call a function after an element has been created in jquery?

I want to call a function after an element has been created. Is there a way to do this?

Example:

$("#myElement").ready(function() {
    // call the function after the element has been loaded here
    console.log("I have been loaded!");
});

Upvotes: 36

Views: 106903

Answers (9)

snnsnn
snnsnn

Reputation: 13678

Creating an element does not mean much, unless it is inserted into the page. I think that is what you mean by ready function.

The onLoad event is limited to certain elements only, and is not supported for div or p elements. You have to options:

You can use setInterval function to check the existence of the element. Once the element is found, you can clear the interval:

var CONTROL_INTERVAL = setInterval(function(){
    // Check if element exist
    if($('#some-element').length > 0){
        // Since element is created, no need to check anymore
        clearInterval(CONTROL_INTERVAL);
    }
}, 100); // check for every 100ms

The second and the more idiomatic way is adding a mutation observer on the target element, and checking if the element is one of the elements inserted elements whenever target is mutated, i.e new element is added:

let el = document.createElement("div");
el.innerHTML = "New Div";

const targetNode = document.querySelector("body");

const observerOptions = {
  childList: true,
  attributes: true,
  subtree: false
};

function callback(mutationList, observer) {
  mutationList.forEach((mutation) => {
    mutation.addedNodes.forEach((node) => {
      const isAdded = node.isEqualNode(el);
      console.log(isAdded);
    });
  });
}

const observer = new MutationObserver(callback);
observer.observe(targetNode, observerOptions);

document.body.appendChild(el);

https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

There are two more alternatives, adding event listener for DOMNodeInserted or DOMNodeInsertedIntoDocument events but since MutationEvent is deprecated, it is best to avoid them.

https://developer.mozilla.org/en-US/docs/Web/API/MutationEvent

Upvotes: 5

Piotr
Piotr

Reputation: 541

old thread, but in my case i had a situation with a big append-tree, and i wanted to do some initialization in-line so to speak, and did the following:

$("<div>").append(
  ...
  $("<div>").foo(...).bar(...).etc(...).each(function(){
    // init code to run after chain of init functions called
  })
...    
)

Upvotes: 0

K6t
K6t

Reputation: 1845

check out .live() its best after the element created,,

$('.clickme').live('click', function() {
      // Live handler called.
});

And then later add a new element:

$('body').append('<div class="clickme">Another target</div>');

Upvotes: 1

Dimitar Nikovski
Dimitar Nikovski

Reputation: 973

Sometimes this is needed for a DOM element created/loaded outside of your own script, either by a different js library or an event outside of your direct control.

For such scenarios, I always set an interval which checks periodically whether the target element exists and if this is true, the interval deletes itself and runs a callback function.

For this, I have a predefined function which I reuse:

function runAfterElementExists(jquery_selector,callback){
    var checker = window.setInterval(function() {
     //if one or more elements have been yielded by jquery
     //using this selector
     if ($(jquery_selector).length) {

        //stop checking for the existence of this element
        clearInterval(checker);

        //call the passed in function via the parameter above
        callback();
        }}, 200); //I usually check 5 times per second
}

//this is an example place in your code where you would like to
//start checking whether the target element exists
//I have used a class below, but you can use any jQuery selector
runAfterElementExists(".targetElementClass", function() {
    //any code here will run after the element is found to exist
    //and the interval has been deleted
    });

Upvotes: 5

Thomas Clayson
Thomas Clayson

Reputation: 29935

How are you creating the element?

If you're creating it in the static HTML then just use .ready(handler) or .on("load", handler). If you're using AJAX though that's another kettle of fish.

If you're using jQuery's load() function then there's a callback you can run when the contents been loaded:

$('#element').load('sompage.html', function(){ /* callback */ });

If you're using jQuery's $.ajax or $.get/$.post functions then there's a success callback in that:

$.ajax({
  url: 'somepage.html',
  success: function(){
    //callback
  }
});

If you're just creating the element and appending it like this:

$('body').append('<div></div>');

Then you can do this instead:

$('<div />', { id: 'mydiv' }).appendTo('body').ready(function(){ /* callback */ });

But this won't matter - because it's synchronous (which means that the next line of code won't run until it's added the element to the DOM anyway... - unless you're loading images and such) so you can just do:

$('<div />', { id: 'mydiv' }).appendTo('body');
$('#mydiv').css({backgroundColor:'red'});

But acctually, saying THAT you could just do this:

$('<div />', {id:'mydiv'}).appendTo('body').css({backgroundColor:'red'});

Upvotes: 49

MEAbid
MEAbid

Reputation: 550

you can try this code

$('body').on('click', '#btn', function() {
  $($('<div>').text('NewDive').appendTo("#old")).fadeOut(0).fadeIn(1000);
})
#old > div{
  width: 100px;
  background: red;
  color: white;
  height: 20px;
  font: 12px;
  padding-left: 4px;
  line-height: 20px;
  margin: 3px;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Test</title>
    <link rel="stylesheet" href="./index.css">
  </head>
  <body>
    <div>
      <!-- Button trigger modal -->
      <button type="button" id="btn">Create Div</button>
      <div id="old">

      </div>
    </div>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  </body>
</html>

Upvotes: 1

David Hoerster
David Hoerster

Reputation: 28701

You may want to look into jQuery live events. You attach an event handler to a selector that either matches now or after additional elements are created in your DOM.

So if you have a <ul> and you dynamically create new <li> items, in your $(document).ready() you can wire up a selector to an event handler so that all of your <li> elements will be wired for that event.

Here's a jsFiddle sample that demos live.

Hope this helps.

Upvotes: 7

Tomgrohl
Tomgrohl

Reputation: 1767

$("<div id=\"elem\"></div>").appendTo("#parent").each(function(){

   console.log("I have been created!");

});

Upvotes: 0

Gerry
Gerry

Reputation: 6012

The most straight-forward is to directly invoke the callback after creating the element :)

Upvotes: -1

Related Questions