I'm creating and removing HTML from inside a div with jQuery (shopping cart, adding/removing items). I need to access the .click() event of a link inside this div, but it only works when the page first loads - after that link is removed then re-added it doesn't respond to any jQuery events.
I've tried functions both inside and outside of $j(document).ready(function() {}. How can I make events work on this link again after re-creation?
Use .delegate() instead of .click() (which is short-hand for .bind('click')):
$(<root-element>).delegate('a', function () {...});
Attach a handler to one or more events for all elements that match the
selector, now or in the future, based on a specific set of root
elements.
Source: http://api.jquery.com/delegate/
The <root-element> can be the document element or if you know an element that is always present that is a descendant of the document element it is best to use that element.
You need to either reattach the event every time you overwrite the content of your container div or set handler using live/delegate/on depending on the version of jQuery you use.
Second method is in general more elegant, but has drawbacks. In particular you cannot cancel the default action from cascaded even attached to the container.
The .click() event only works for elements that are present with the function is called. You need to look into using either .live() or .delegate() to attach listeners to elements that are dynamically created after $(document).ready()
Try using .detach() instead of .remove(), that will keep the events. Alternatively use event delegation.
Related
is there any difference between this both selectors in combination with a click event?
$("#container").find(".element").on("click",function(){
})
$("#container").on("click", ".element",function(){
})
For me I think technically the effect and consequence will be the same?
Thank you
They are not the same.
The first example using find().on() looks for the .element class in the DOM and adds the event handler to it. It will not work for any elements with that class that are added to the DOM later in the page lifecycle.
The second example using on() with a selector is a delegated event handler, and will therefore work for all matching elements in the DOM as well as those added later.
I have some javascript that successfully clones a template and appends the resulting html to a div. However when I try to reference an element of the clone it is not accessible, even though if I place the exact same element with the exact same ID (confirmed with Firebug) outside the template (and the cloning system) it is accessible. I believe I need to do an update of some kind after cloning but I am not sure. The code I am trying to use to access the (cloned) element (does not log anything to console and is not working) is:
$("#depminusbutton0").on("click", function () {
console.log('I triggered minus 0');
});
And depminusbutton0 shows up like this in firebug inspect element once cloned (doesn't exist prior to cloning, as ID 0 is inserted dynamically:
<a id="depminusbutton0">
Any ideas how I can make this element accessible?
Two possibilities I can think of:
You are installing the event handler before the element exists so it can't find the element to attach the event handler to?
You have a conflicting ID elsewhere in the document.
If you're going to use this form of event handling:
$("#depminusbutton0").on("click", fn);
Then, the #depminusbutton0 element must exist at the time you run that line of code. It will search the DOM for that element at the time you run the code and will not hook up to an element that matches that ID that you create in the future.
You can work around that issue, either by running that line of code AFTER you create the #depminusbutton0 element and insert it in the DOM or you can switch to use delegated event handling which attaches the event handler to a common parent that does exist before you've created the child element.
To see more about how delegated event handling works, see these references:
jQuery .live() vs .on() method for adding a click event after loading dynamic html
Does jQuery.on() work for elements that are added after the event handler is created?
The general idea would be like this:
$(some parent selector).on("click", "#depminusbutton0", fn);
If you have multiple elements with the #depminusbutton0 id, then you will have to fix that and only have one element with that id. Often times with clones, you want to use a class name rather than an id since you can have multiple elements with the same class name.
Are you attaching the event to an element that doesn't exist yet? As described in the jQuery documentation:
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on().
Just make sure you are attaching the event to the cloned element after you create it.
$(document).on('click', '.class-or-id-name', function() {
console.log("Heyyy its clickable");
// do more stuff
});
I need to have multiple .click() functions populated on page load, based on how many image records are stored within a mysql database.
so far i have a page that will nicely switch between photos with a <ul> of image buttons
but i have to hand write the jquery that deals with it.
is there a way that i can populate a .js file with the correct amount of .click() functions based on the amount of records on in the data base.
In addition to Alex's answer, if you want to set the click event of elements that don't exist yet or haven't been added to the page, you could do:
$(body).on('click','a.record',function(){
//any existing or future a element with class record will have this click function
});
Instead of adding a separate onclick handler to each element, you should use event delegation and attach a single event handler to some container. Said event handles would catch all the onclick events , as the bubble up through DOM.
You don't need to write a click() for each unique element.
Instead, you could select a bunch of elements with a selector, such as $('a.record') and then chain click() to that...
$('a.record').click(function() {
// Any `a` element with a class of `record` was clicked.
});
The disadvantage of doing it this way is you add a bunch of event listeners and it won't be triggered for future elements.
As others have mentioned, event delegation using on() (if using a newer jQuery) or delegate() (if using an older) is the best, as it only attaches one event listener and will work with future elements added after the event is attached.
$(document).on('click', 'a.record', function() {
// Any `a` element with a class of `record` was clicked, now or in the future.
});
I've used document here, but you should use the nearest ancestor which won't change, which may be the ul element you have described.
I've a table generated dynamically by jQuery, using
this.html("<table><tr><td><div>Click Me</div></td></tr></table>");
within the table, I've a few divs (my sample shows only one to keep things simple), which I want to add click event handler to. I'd like to keep html clean and use as much of jQuery power as I can, but since I'm doing an 'eval' type of things I can't quite figure out how to do that.
I know, that I can use $("div[some attribute selector]").on("click", {}, clickHandler);, but is it a good idea in my case?
You need delegated events. To do that, simply use jQuerys on() method like this:
$(document.body).on('click', 'div', function( event ) {
// do something
});
Ref.: .delegate(), .on()
What is that? Almost all events do what we call 'bubble'. That means, if you click on a nested element, your browser looks if there is any click-event handler ascociated on that node. If so, it executes them and then the parent of that element is also asked if there is any click-event handler. This continues until either some handler prevents the event from further bubbling or we have reached the document.documentElement (html).
So, you should change the above document.body into the closest node relative to your dynamically added elements.
You can use either use live or delegate to do that
Hello I am having a problem with .html function in jquery. event listener doesn't work anymore everytime i remove the script from the codes and paste it again. can you help me how to reactive script after it's re-paste in html.
You can set your events using .live() method. Like:
$("#submit_button").live("click",function(e){
});
This way if you are adding/removing html from your page using .html() method, the events will remain intact.
Hope that helps.
You could use the .live() method to register the event handler which will preserve it even if the corresponding DOM element is recreated. Example:
$(function() {
$('#someid').live('click', function() {
//
});
});
I guess you are changing the inner html of some container with .html() function of jquery and the events you assigned are lost after the process. There are two approaches you can take:
If the content doesn't change use the .detach() function to remove and insert your elements back. The .detach() function preserves and event handlers attached to the elements you detach. However if you are inserting a different content then use .live() event to assign your events. The events that are assigned with .live() will be recreated when a element with the same selector is inserted into the dom.
Use this as an example:
$('a.button').live('click', function(){
//anchor tag clicked.
alert('Button has been clicked');
});
The .live():
Attach a handler to the event for all
elements which match the current
selector, now and in the future.
The .live() method is able to affect
elements that have not yet been added
to the DOM through the use of event
delegation.
This means that you add and remove html from your page with .html() and your events will still perform.
See the jQuery website for more information on .live()
A quick jsFiddle example.