I have a PHP file that is generating HTML elements, and is being called from AJAX when the page loads. What I am looking to do is apply JQuery to the dynamically generated elements, so for each time a label, generated from the PHP file, is clicked something happens. I tried placing the JQuery code in the PHP file and echo it out, but that didnt work, I also placed the code in the HTML page, where the AJAX is being called, but that didnt work either.
In my HTML I have:
<body onLoad="javascript:getLabels();">,
This calls the php file through AJAX:
function getComments() {
var thePage ='loadLabels.php';
...
The PHP file as the line:
echo '<label id="labellink" class="ldClass">Label </label>';
which could be more then one label in the page once loaded, but all in their one <form>
, so I need to use JQuery so once the labels are loaded and I click on them, I can make something happen.
Edit Thank you for correcting me on that. Since it is depreciated, I haven't used it in a while.
I'm sure this counts as more of a "hack" than a solution, and I will openly welcome downvotes if necessary, but you could put the post-AJAX functionality within the success function.
Also, older versions of jQuery used a function called .live()
which would look for an element whether it was in the DOM or not. It's depreciated in the newest version of jQuery, but if you're willing to take that leap, I know for a fact that it worked in 1.5. (I'm talking about something like $(a).live('click', function () { });
).
For the record, I would love to have posted this as a comment rather than an answer, but I don't have enough street cred for that yet.
What you want is jQuery "live" http://api.jquery.com/live/
Edit: You want .on() in the newer versions of jQuery since .live() has been depreciated: http://api.jquery.com/on/
See comments below for more info.
Using .delegate() is the best way I have ever used.
.on()
(Documentation) provides a method of creating handlers for dynamic elements, that may not necessarily exist when the handler is created.
To use .on()
, you need to attach the handler to a non-dynamic object higher in the DOM tree. The click will propagate up the tree from the child element, at which point the handler (delegate) attached with .on()
will use the provided filter to see if the click originated in the correct object (which would be your dynamic object).
$('body').on('click', '.dynamic_element', function() {
// Handler code
});
In this case I used body
, because it won't disappear and take the handler with it. You can attach the handler to any object that is an ancestor of .dynamic_element
, as long as it is a static element. Closer is generally better, but if your page is very dynamic, body
will work.
The whole idea behind .on()
is that handlers must be attached to an existing DOM element. If an object doesn't exist yet, you cannot attach a handler to it, and if your element is removed, the handler is removed as well. This is why $('.dynamic_element').click()
won't work, unless .dynamic_element
already exists. So, with .on()
, we just attach the handler to something we know does exist (and won't disappear). This handler is called a "delegate". It watches for events from its child objects, which by the nature of DOM elements, propagate up the tree.
There are 2 ways to achieve what you want.
1: attach the events to the link inside the onSuccess of your AJAX call to retrieve the content. That way when new content are added to the DOM, you'll attach the necessary events to those specific elements.
2: the recommended solution is to use event delegation. Basically, instead of attaching the events to specific elements, you attach a single event to the parent element container, and when the event is triggered, it based on conditioning the clicked target (if it has a specific class per se) you perform the specific actions. This is a technique used to handle fluid/changeable content without having to r-eattach events to the specific elements. jQuery's .on() API method provides such solution elegantly: http://api.jquery.com/on/
For example:
$("#container").on("a.changeColor", "click", function() {
$(this).toggleClass("newColor");
});
You delegate/attach the event to the parent element with the id="container", tell it that you want all the child anchor elements with the "changeColor" class to toggle the "newColor" class. Even after you update and change the inner content of the #container element, the new elements with class "changeColor" will still inherit the behavior when clicked.
Just an example of dynamic created elements and onload bound events
var a = $("<a>").attr('href','#')
.attr('class','elem')
.text('click me')
.prependTo('body');
$(document).on("click", "a.elem", function(e){
e.preventDefault();
alert("Goodbye!");
});