Andrew
Andrew

Reputation: 238707

jQuery: How to call a jQuery plugin function on an element that hasn't yet been added to the DOM?

I have a jQuery plugin that I am using:

$(document).ready(function(){
    $('.elements').fancyPlugin();
});

This works great until I start adding new elements:

$.get('ajax.html', function(data){
    $('#container').html(data);
});

I could call the plugin function again like this:

$.get('ajax.html', function(data){
    $('#container').html(data).find('.elements').fancyPlugin();
});

...except that the AJAX is happening inside another jQuery plugin that shouldn't have to know about the fancyPlugin().

How can I apply this plugin to all current and future elements?

Upvotes: 22

Views: 6603

Answers (7)

programaths
programaths

Reputation: 891

Another way of doing this is creating your own event :

var container=$('#container');
$.get('ajax.html', function(data){   
   container.html(data);
   $('.elements',container).trigger('added.yourns');    
});

container.on('added.yourns','.elements',function(){
  $(this).fancyPlugin();
});

Then, when adding ellements, simply trigger the event with the trigger method!

var aDiv=$('div');
aDiv.appendTo(someNode);
aDiv.trigger('added.yourns');

Doing so will enable you to attach any behaviour in any javascript file !

Upvotes: 11

Paul
Paul

Reputation: 141829

I think this will work in all browsers except IE:

document.body.addEventListener("DOMNodeInserted", function(event){
    var $elementJustAdded = $(event.target);
    if ($elementJustAdded.hasClass('elements')) {
        $elementJustAdded.fancyPlugin();
    }
}, false);

Upvotes: 15

Darin Dimitrov
Darin Dimitrov

Reputation: 1038780

If those elements are added with AJAX you could use the .ajaxSuccess() method:

$('#container').ajaxSuccess(function(result) {
    $('.elements').fancyPlugin();
});

And here's a live demo.

Upvotes: 2

Milimetric
Milimetric

Reputation: 13549

Interesting. Essentially, you'd like something like:

$('selector').ready( ... do something ... );

The problem is that kind of logic isn't available. Elements loading on the page don't trigger any specific events I'm aware of, they just inherit CSS from the DOM nodes above them. What I would do is just, from the $.get success function, trigger a custom event. The rest of your code can hook into that event to do any plugin reloading work that may be needed. You can pass a list of relevant selectors with the event, and use that to invoke the appropriate plugins (you can keep a set of selector -> plugin refresh function relationships in a hashtable)

Upvotes: 0

spliter
spliter

Reputation: 12569

What if you make something like this?

$(document).ready(function(){
    $('.elements').live('load', function () {
        $(this).fancyPlugin();
    })
});

The events are not re-binded after ajax calls or within the content they return. live() attaches a handler to the event now and in the future."

Upvotes: -1

William
William

Reputation: 8067

Have you looked at the jQuery .live event handler? It automatically binds when a new item is added to the dom if it meets the specified requirements.

http://api.jquery.com/live/

Upvotes: -1

Tgr
Tgr

Reputation: 28160

Have your AJAX handler trigger some custom event like contentAdded, and bind fancyPlugin to that event.

Alternatively, you can use DOM mutation events to call fancyPlugin for any change in the container. Native browser support isn't quite there yet, but there are plugins which should take care of that.

Upvotes: 0

Related Questions