jQuery.click not working after adding element to the DOM - javascript

I have a simple jQuery('div#star').click(function.
The function works once when the DOM is initially loaded, but at a later time, I add a div#star to the DOM, and at that point the click function is not working.
I am using jQuery 1.4.4, and as far as I know, I shouldn't need to use .live or .bind anymore. There is never more than one div#star in the DOM at any one time. I tried changing from id="star" to class="star" but that didn't help.
Any suggestions on how to get this working or why it isn't working?
I've had the .click inside the jQuery(document).ready, and in an external js file, and neither works after adding the div to the DOM.

This works with jQuery 2.0.3
$(document).on('click', '#myDiv', function() {
myFunc();
});

As of jQuery 1.7, the .live() method is deprecated. The current recommendation is to use .on() which provides all functionality covering the previous methods of attaching event handlers. Simply put, you don't have to decide any more since on() does it all.
Documentation is handily provided in the help for converting from the older jQuery event methods .bind(), .delegate(), and .live()

You still need to use live events.
http://api.jquery.com/live/

try
.on('event', 'element', function(){
//code })

You need to use either live or delegate here. Nothing has changed in this department since jQuery 1.4.4.
Try to think of it like this: click and bind attach an event to the element itself, so when the element disappears, all the information about the event does too. live attaches the event at the document level and it includes information about which element and event type to listen for. delegate does the same thing, except it attaches the event information to whatever parent element you like.

user "live" method $("div#star").live("click", function() {});
Doc

You can use delegate instead on :
$(document).delegate('click', "selector", function() {
//your code
});
I hope it will help.

Related

jQuery live("click", function() {...}) doesn't work for body

I am trying this simple code here. It doesn't work for either the actual click event or the one which is commented out. Can anybody explain why? I have had issues with not previously also...
That's simply because the live function, which was long deprecated, has now been removed from jQuery.
Replace
$("body").live("click",function() { alert("coo"); });
with
$("body").on("click",function() { alert("coo"); });
Look at the top right of this page : "removed 1.9".
.live has been deprecated in jQuery since v1.7, and has been removed in v1.9.
You should replace it with .on().
.on has 2 syntaxes for binding elements, whereas .live only had 1.
If the element exists at the time you are binding, you do it like this:
$('.element').on('click', function(){
});
You can even use the shorthand:
$('.element').click(function(){
});
If the element does not exist at the time, or new ones will be added (which is what .live was normally used for), you need to use "event delegation":
$(document).on('click', '.element', function(){
});
NOTE: You want to bind to the closest static element, not always document.
The live() method has been deprecated and deleted. Use on().
If you are using jquery 2.0 version then you have to get the migrate 1.0 too
see this: http://jsfiddle.net/CRYDV/1/
otherwise you have to work with .on() handler as suggested in above answers.

jquery function works with live, not with on

trying to use the preferred on method call but the code is not working with on but does work with the live method.
Okay, I have a simple button element.
<button id="EditVal" name="EditVal" style="btn" value="Edit Debt">Edit Debt </button>
If I use the live method this code works:
$("#EditVal").live("click", function(e){
alert('Edit this Val');
})
But this doesn't
$("#EditVal").on("click", function(e){
alert('Edit this Val');
})
What am I doing wrong?
You're using on() like bind(), not like live(). To use it like live(), you should write:
$(document).on("click", "#EditVal", function(e) {
alert('Edit this Val');
});
Note that, for performance reasons, it's preferred to call on() on a non-dynamic ancestor element instead of document, i.e. to use it like delegate() instead of live().
Using on as you are attaches the event on page load. As you are dynamically loading the content, you need to use on as you would delegate by placing the handler on a parent element, and passing a filtering selector.
Try this:
$("#ParentOfEditVal").on("click", "#EditVal", function(e){
alert('Edit this Val');
})
If your dynamically dropping a html element on the page then you need live. Here is why, on is set to work on EditVal if EditVal exsists on pageload. Since it does not I am assuming, the live function is needed as that can be bounded late after the initial page load. I think that was the original thought behind live in the first place. Any particular reason why you are using on instead of live?
The logic is that .on() binds the event to an object that is in the DOM. Then you give, as a parameter, the selector to find the child-element you want the trigger the event.
$("#parent_has_to_be_in_dom").on("click", "#myButton", function(event) {
// should work like live
alert("well hello");
});

Why when initiating $.click() several times, and if the link is clicked once, it captures it more than once?

I have something like:
function init(){
$('.btn').click(function(){
//do something;
}
}
And when new content is added via ajax, I'm calling init(), so that click event applies to new buttons. But when I click it once, it captures several clicks (as many times as I called init()). It makes sense, but how to avoid it?
jsFiddle link: http://jsfiddle.net/s2ZAz/8/
Solutions:
* Use $.delegate() - http://api.jquery.com/delegate/
* Use $.live() - http://api.jquery.com/live/
Less preferred, but still, solutions:
* Use $.off() - http://api.jquery.com/off/ or $.unbind() - http://api.jquery.com/unbind/
click says, "for every object matching the selector, hook up this click listener". You probably want something more like delegate that says "for every object that will ever match this selector, hook up this listener".
$(document).delegate('button', 'click', function() {
});
You will still get double callbacks if you call init twice, but in this manner, you won't have to call init twice, because as new objects are added, they'll already be assigned to click listeners.
Note that document above should be replaced with the nearest persistent ancestor, as per Greg's comment below.
Demo.
Since jQuery 1.7, you can preferably use the .on() function to achieve the same effect.
Demo.
You can use the unbind method to remove the event handler (or the off method if you're using the new jQuery 1.7 syntax for attaching handlers)
Better yet, you can use the live method, to set up the event handler for any elements that are added to the page in the future and match the given selector. In this way you only have to call init once.
$("body").delegate("button", "click", function() {
alert('I\'m annoying!');
});
$('div').append("<button>Click me, I will alert twice</button><br/>");
$('div').append("<button>Click me, I will alert once</button><br/>");
$('div').append("<button>Click me, I will not alert at all</button><br/>");
Try it out
As mentioned by David, and as per liho's delegate example (loved the way the fiddle cascaded how many times the alert would pop!!), the problem is with multiple bindings, which can be solved with .live() (deprecated) or .delegate() (being phased out), or .on() (the preferred). However, it is a mistake to delegate listening to the document or even body node in terms of performance.
A better way to do this is identify an ancestor of the button that will not ever be destroyed. body is an easy choice, but it's almost always the case that we build our pages with wrapper elements of some sort, which are nested one or more levels deeper than body and therefore allow you to set fewer listeners.
HTML:
<div id="someWrapper">
<div class="somethingThatGetsDestroyed">
<button>Click Me</button>
</div>
</div>
JS using jQuery 1.7+:
$('#someWrapper').on('click', 'button', function() {
alert('Clickity-click!');
});

jQuery: How to add event handler to dynamically added HTML elements?

I have the following code:
$(document).ready(function({
$(".click").click(function(){
alert(' The Button Was Clicked !');
});
}));
This works fine.But If I add an element with the same class to the web page, as shown here:
$('#clicked').click(function(){
$("#area").append("<button class='click'>Click me</button>");
});
Then the event handler I added before to the .click class won't work for this new element.
What's that best way to add event handlers to elements that were added dynamically ?
UPDATE
It's been a while since I posted this answer and things have changed by now:
$(document).on('click', '.click', function() {
});
Since jQuery 1.7+ the new .on() should be used and .live() is deprecated. The general rule of thumb is:
Don't use .live() unless your jQuery version doesn't support .delegate().
Don't use .delegate() unless your jQuery version doesn't support .on().
Also check out this benchmark to see the difference in performance and you will see why you should not use .live().
Below is my original answer:
use either delegate or live
$('.click').live('click', function(){
});
or
$('body').delegate('.click', 'click', function() {
});
In reference to your code, the way to do it would be.
$('.click').live('click', function(){
... do cool stuff here
});
Using the .live() function allows you to dynamically attach event handlers to DOM objects.
Have fun!
for all the elements added dynamically to DOM at run time , please use live
http://api.jquery.com/live/
After jQuery 1.7 the live method just points to .on() method. And I had alot trouble finding out how to bind event handler to element which is appended to the DOM after its loaded.
$('body').live('click', '.click', function(){
//Your code
});
This worked for me. Just a little tip for those having trouble with it also.

Does the jQuery .unbind() method only work on jQuery created events?

I am trying to unbind all event handlers for all elements that are inside a particular container. Like a DIV. But those events have been bound/registered not using jQuery. Some are bound the manual way with onclick="...." or using regular native JavaScript.
But when I do something like this
$('#TheDivContainer').find('div,td,tr,tbody,table').unbind();
It does not appear to work. Which leads me to believe that the .unbind() only works if the events have been originally bound by jQuery.
Is that true? Is there another way of unbinding all events from a group of elements?
Thanks!
You are right. As in the API:
Any handler that has been attached
with .bind() can be removed with
.unbind().
Unbind will only work on jQuery created events as all methods that does this (addEventListener, and attachEvent) requires the both the node, the eventname, and the handler as an argument. bind takes care of storing these for you..
By the way, DOM0 style event listerens (.foo = function(...) can only by removed by setting the same property to something else like null.
You could always do this:
$('#TheDivContainer').find('div,td,tr,tbody,table')
.unbind('click')
.attr('onclick', ''); // edited to change null to ''
etc. for all appropriate event types.

Categories