jQuery on() with ajaxed content - javascript

I am trying to bind click handlers to incoming ajaxed content. I used to use 'live'
$('#div').live('click', function(event) {
alert('I got clicked, Live style');
});
But now as my site is getting more complicated, I am realizing how crazy things can get using live and having everything bubble to the top of the DOM. Which is not ideal.
So I started using on(),
$('#div').on('click', function(event) {
alert('I got clicked, On style');
});
But I miss the fact that using live() I could just initialize the click handlers once and be done with it instead of reinitialize them every time new content is loaded. Is there a best of both worlds?
Is there a better way to "reload" click handlers to recognize new ajax content aside from creating the handlers in the ajax callback function? To me that seems highly suspect. Whats the appropriate way to do this?

As of jQuery 1.7 the following .on() event binding is equivalent to the deprecated live:
$(document).on('click', '#div', function(event) {
alert('I got clicked, On style');
});
You can also bind the event to some fixed element further down the DOM which doesn't get re-generated, this functionality would be the same as .delegate():
$('#parentofdiv').on('click', '#div', function(event) {
alert('I got clicked, On style');
});
It is advisable to use the second form to narrow down the scope of the event binding as much as possible to make it easier to maintain.
Edit: For the record, what you originally did in your post would be the preferred replacement for your .bind() calls in your code.

Have you looked at using .delegate? http://api.jquery.com/delegate/

jQuery's on() method can be used to attach various events to already existing items as well as items added by ajax calls to the DOM in the future:
$(document).on("click", ".ajax-added-content", function(event) {
alert('I got clicked, On style');
});

It is possible to do what you want with
.on()
and it is actually the recommended method.
.live()
is deprecated as of jquery 1.7.
You can attach your event to the body and use this overload of "on" to get the functionality you desire. Check the next to last example in jquery's doco of .on
$("body").on("click", "#div", function(){
alert('I got clicked, On style');
});

Related

jQuery .on trigger event listener

There is a best practice to invoke a jQuery change handler immediately afters its definition to re-use the code and initialise the GUI, like
$("#mySelect").change(function() {
$("#myTextField").val( $(this).text());
}).change(); // here the element is immediately triggered, so one does not need a separate code path for the init-case
Without the immediate call using .change() the GUI would not reflect the initial value of #mySelect in #myTextfield.
With newer versions of jQuery I would like to use event-delegation and do the same stuff using the .on() API.
$("#myForm").on('change', '#mySelect', function() {
$("#myTextField").val( $(this).text());
}).change();
This does not work anymore, because the .change() is not triggered on the right element and not with the right event.target, so jQuery can't call my event handler.
This works, but does no longer reflect the best practice without the separate init code-path:
$("#myForm").on('change', '#mySelect', function() {
$("#myTextField").val( $(this).text());
});
$("#mySelect").change();
Question: Any good way to solve this, without re-selecting the element and triggering the event?
You would need to find all the elements and call trigger on them... Because delegation delegates the handling to some other element up the DOM (as you likely know)
You would essentially have to do what you have done in your 3rd example. I know of no other way to achieve this.

Use JS that is already loaded, on HTML loaded via jQuery's load() function?

Not sure if this is posible or not, but I'm trying to use JavaScript that I loaded via a script tag when the page was initially requested on dynamic HTML that was loaded via jQuery's load() function.
Example: http://jsfiddle.net/3MR43/
As you can see in the example, after clicking a link in the pop up box, the link goes. The problem is that the link was suppose to be stopped, and you were suppose to see an alert.
However, if I paste the HTML that I am loading via jQuery, it works, so the code is fine.
Description
You need jQuery .live() or .on() method to bind events to dynamically created html.
Choose .live() or .on() depending on the version of jQuery you are using.
.live() Available since jQuery 1.3. Attach an event handler for all elements which match the current selector, now and in the future.
.on() Available since jQuery 1.7. Attach an event handler function for one or more events to the selected elements.
Check out my sample and this jsFiddle Demonstration
Sample
... for jQuery.live()
$('.lang').live("click", function(e) {
e.preventDefault();
alert('Testing..');
});
... for jQuery.on()
$('.lang').on("click", function(e) {
e.preventDefault();
alert('Testing..');
});
More Information
jsFiddle Demonstration
jQuery.live()
jQuery.on()
The problem is your .click will do it for only elements that exist at that time. If you want to do it for all potential future elements that that selector will match, you want to use on() (delgate() or live() with older versions of jQuery).
The $('.lang').click() event must be registered after the element is created!
You need a callback on the load function to register this.
You need to use live to attach handlers to elements that are loaded dynamically.
Try this, it will solve your problem.
$('.lang').live('click',function(e) {
e.preventDefault();
alert('Testing..');
});
You have to use on function for dynamicly loaded elements:
$('.open_lang').click(function(e) {
e.preventDefault();
$('#popup').load('http://skins.thehabbos.org/pop_up/language.php').css('display', 'block');
});
$('body').on('click', '.lang', function(e) {
e.preventDefault();
alert('Testing..');
});
(live and delegate are deprecated in JQuery 1.7+ which is the version of your JSFiddle)
Fixed JSFiddle

Adding action to DOM element added through AJAX

having a slight problem here. I have a post stream on my site, each post has buttons that execute different actions that are setup in my $(document).ready() now, to add posts I make an AJAX call that returns the html for the new post element, but the actions in the my previous $(document).ready() do not apply to this new element, and adding it in a $(document).ready() for the element causes the buttons from the already posted elements to be duplicated.
Any idea how I can get around this?
The elements that added after documnet ready event don't accept binding events (you call it ations). You may use .click() or .hover() or .bind('click', function(){}) and neither works. You can use jQuery .live() or .delegate()
Using delegate is much better because when you use live for click (for example) it means you'r listening to any click happening on your document and determining if it's that click you where looking for or not? But with delegate you limit the clicks that computer process to find your click.
$('.myinput').live('click', function(){
// do something if a click happened and it was on my input
})
$('.myDiv').delegate('.myinput', 'click', function(){
// do something if a click happened in my div and it was on my input
})
if you use $(selector).live(eventType, handler) it should add events to all elements matching that selector.. even if they are added after the DOM is loaded:
http://api.jquery.com/live/
like #Mohsen said there was a way to solve this using .live()
now its depreciated and there is alternate way:
How to change depreciated method?
$( 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+
link: jQuery .live()
I had thesame problem and this last one with ".on" works fine for me.
Maybe someone have thesame problem and use it too

Why jQuery on click event not getting triggered?

I have an group of checkboxes with id's starting with somename and I want catch the click event of these checkboxes. Previously I have done this through jQuery. i.e.:
$("input[id^='somename']").click(function(){
// my code follows here
})
but this is not working this time around. Why?
P.S. The element is created via JavaScript after the page is fully loaded after making some ajax request. I don't know if this may be the problem?
just use live if elements are created after the page is loaded.
$("input[id^='somename']").live('click', function(){ // my code follows here })
P.S : Your search selector is "somename" but you search it on the attribute ID, are you sure that you don't want :
$("input[name^='somename']").live('click', function(){ // my code follows here })
instead?
This indeed could be the problem. Replace .click with .live()
$("input[id^='somename']").live('click', function(){ // my code follows here })
and you should be fine.
Since a call to .click is just a shortcut for .bind('click', fnc), this will not work if the element is not in the DOM when calling this. Even better than using .live() would be to use .delegate(). Have a read:
.live(), .delegate()
Using the standard binding functions only works on elements that exist at the time of the bind. You need to use something called event delegation, where elements further up the DOM tree are notified of events on descendant elements. The best way to do this is with .delegate():
$('#containingElement').delegate("input[id^='somename']", 'click', function(){
// your code here
});
This assumes that you have an element #containingElement that contains all the elements that you want to capture the events on.
NB that other answers recomment live. live and delegate use the same backend code, but for various reasons delegate is more efficient.
I believe that because you want this applied to dynamically created elements in the DOM you are going to have to use the the jQuery .live() method:
$("input[id^='somename']").live('click', function(e) {
// Your code
});
Instead of .click() try .change() event.

jquery late binding

i have a code that bind's on click action on page load, it is a link. When i clicking it, it send ajax request and replace content in some div with jquery append() function. This new content has a links and i need to bind some action for them, but i could't.. bind did't work i think, because jquery append doesn't update DOM tree. How could i get a late binding?
There are 3 functions that can do this:
$(selector).live(events, data, handler); - jQuery 1.3+ - version deprecated: 1.7, removed: 1.9 (reference)
$(document).delegate(selector, events, data, handler); - jQuery 1.4.3+ - As of jQuery 1.7, .delegate() has been superseded by the .on() method. (reference)
$(document).on(events, selector, data, handler); - jQuery 1.7+ - preferred (reference)
It's generally adviced to use on() and it's use is simple and probably preferred way.
The first selector must exist when calling the function and may not be deleted or the event will be gone too (this can be document).
The first parameter is the event (e.g. "click")
The second parameter is the selector of which you want to bind the event on.
Then finally you can add some custom data and a function to the event.
Here's some sample code:
// Make sure the DOM is ready
$(function() {
// Bind the click event to the function
$(document).on("click", "a.class", function(event) {
// Put your code here.
});
});
Late binding is now available by utilizing jQuery's live() event:
$('a.my-links-class').live('click', function() {
// do your link action here
});
Method .live in JQuery 1.9 is deprecated.So now u can do like this:
$("body").on("click", ".classname", function() { ... })
the .live() event was deprecated from verions 1.9 up.
For anyone using later version of Jquery they can use the .on() event, it works pretty much in the same way.
You need to use jQuery's live function, which will bind an event to all elements that match a selector, no matter when they were created.
You can use jQuery 1.3+'s $().live(event, function) function. $("a").live("click", myClickFunc) will bind myClickFunc just like $("a").click(myClickFunc) or $("a").bind("click", myClickFunc), but the events will be bound "live", so elements that are added to the DOM after that function call will also be bound.
You can remove live-bound events with $().die().
For more information on $().live, see the documentation for it.
Another option would be to have a function to bind the elements given a certain context (using the $ selector function's rarely-used second parameter):
function myBindEvents(context) {
$("a", context).click(myClickFunc);
}
and call that whenever you update an element with AJAX:
$("<div>").load("...", "...", function(){myBindEvents(this);});
Hope this helps. :)
In my case I am using js library in that I have element variable and code was like
$(element).click(function(){
//some action
});
but that is not working with my late binding element.
So I finally use core js click event
element.addEventListener('click', function() {
//My some action
}, false);

Categories

Resources