xaxa
xaxa

Reputation: 1159

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?

Upvotes: 0

Views: 2053

Answers (5)

suvroc
suvroc

Reputation: 3062

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>

Upvotes: 0

ttzn
ttzn

Reputation: 2613

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.

Upvotes: 0

Romain V...
Romain V...

Reputation: 433

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/

Upvotes: 0

A. Wolff
A. Wolff

Reputation: 74420

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, e.g:

$(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.

Upvotes: 0

vxsx
vxsx

Reputation: 468

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).

Upvotes: 2

Related Questions