简体   繁体   中英

Do function on newly created element with jquery

When I dynamically add a new element, I want to apply some function to it. For example, to turn regular <input> into date-time selector (via some plugin) I need to

$('.dt').dateTime();

The function above only works the first time I add elements during initialization. Whenever I add them later using .append() the function is not applied. For event listeners I use $(document).on() instead:

$(document).on('click', '.dt', function () {});

and it works in any case.

What is the equivalent to use on creation?

On SO I've seen solutions to similar problems that either use function .live() which is now deprecated, or use some sort of plugin which I don't want.

Is there any solution in plain jquery?

It is not possible to listen to element creation in jquery.

In order to initialize something on adding the element to the DOM you have several options:

  1. Use MutationObserver https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver however it doesn't have the best support out there.

  2. Manually initialize the plugin after appending an element (best bet).

According to .live() documentation you can use

Rewriting the .live() method in terms of its successors is straightforward; these are templates for equivalent calls for all three event attachment methods:

$( selector ).live( events, data, handler );                // jQuery 1.3+
$( document ).delegate( selector, events, data, handler );  // jQuery 1.4.3+
$( document ).on( events, selector, data, handler );        // jQuery 1.7+

I try it in jsfiddle and when you set .on function on parent element all elements inside (also in future) will have this event attached

 $( ".main" ).on('click', '.cl', function() { alert('clicked'); }); $(".add").click(function() { $( ".main" ).append( "<p class='cl'>Test</p>" ); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="add">Add</div> <div class="main"> <p class='cl'>1</p> <p>2</p> <p class='cl'>3</p> <p>4</p> </div> 

One other solution ( other regarding @vxsx's answer and depending plugin behaviour) could be to use a delegated event, eg, mouseenter and initialize plugin using it, eg:

$(document).on('mouseenter', '.dt:not(.dt_initiliazed)', function () {
    $(this).addClass('dt_initiliazed').dateTime();
});

One other solution would be to set a fake CSS animation/transition on specific elements .dt and use relevant event animationEnd/transitionEnd to initialize plugin. This would work even for elements added later in the DOM.

On some modern browsers with jQuery you can try :

$(document).on('DOMNodeInserted', '.dt', function(event) {
    $(event.currentTarget).dateTime();
});

This feature is actually deprecated, so I advise you to follow vxsx's answer and either use the MutationObserver facility or, better yet, apply the function manually every time you append a .dt element. It shouldn't require more code than actually setting up an event listener.

You can use MutationObserver to detect new DOM element and force binding on these new items.

You can read this : http://gabrieleromanato.name/jquery-detecting-new-elements-with-the-mutationobserver-object/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM