I have <video> elements added to the page when an image is clicked. A light box with the video pops up. What would be the best way to execute a snippet of jquery to this dynamic video element? I though maybe some form of the .on method might work was not sure.
Edit: I'm using ilightbox for the lightbox which has code that adds in a html video after a lightbox image is clicked.
.on working good for new element in Document object model(DOM)
The .on() method attaches event handlers to the currently selected set of elements in the jQuery object. As of jQuery 1.7, the .on() method provides all functionality required for attaching event handlers. For help in converting from older jQuery event methods, see .bind(), .delegate(), and .live(). To remove events bound with .on(), see .off(). To attach an event that runs only once and then removes itself, see .one()
reference on
Related
I'm curious to know the differences between the bind and live functions.
To me they seem to be almost identical.
I read the benefits of live/bind methods, but it didn't tell me about the differences...
Thanks!
In short: .bind() will only apply to the items you currently have selected in your jQuery object. .live() will apply to all current matching elements, as well as any you might add in the future.
The underlying difference between them is that live() makes use of event bubbling. That is, when you click on a button, that button might exist in a <p>, in a <div>, in a <body> element; so in effect, you're actually clicking on all of those elements at the same time.
live() works by attaching your event handler to the document, not to the element. When you click on that button, as illustrated before, the document receives the same click event. It then looks back up the line of elements targeted by the event and checks to see if any of them match your query.
The outcome of this is twofold: firstly, it means that you don't have to continue reapplying events to new elements, since they'll be implicitly added when the event happens. However, more importantly (depending on your situation), it means that your code is much much lighter! If you have 50 <img> tags on the page and you run this code:
$('img').click(function() { /* doSomething */ });
...then that function is copied into each of those elements. However, if you had this code:
$('img').live('click', function() { /* doSomething */ });
...then that function is stored only in one place (on the document), and is applied to whatever matches your query at event time.
Because of this bubbling behaviour though, not all events can be handled this way. As Ichiban noted, these supported events are click, dblclick mousedown, mouseup, mousemove, mouseover, mouseout, keydown, keypress, keyup.
.bind() attacheds events to elements that exist or match the selector at the time the call is made. Any elements created afterwards or that match going forward because the class was changed, will not fire the bound event.
.live() works for existing and future matching elements. Before jQuery 1.4 this was limited to the following events: click, dblclick mousedown, mouseup, mousemove, mouseover, mouseout, keydown, keypress, keyup
Bind will bind events to the specified pattern, for all matches in the current DOM at the time you call it. Live will bind events to the specified pattern for the current DOM and to future matches in the DOM, even if it changes.
For example, if you bind $("div").bind("hover", ...) it will apply to all "div"s in the DOM at the time. If you then manipulate the DOM and add an extra "div", it won't have that hover event bound. Using live instead of bind would dispatch the event to the new div as well.
Nice read on this: http://www.alfajango.com/blog/the-difference-between-jquerys-bind-live-and-delegate/
Is nowadays (since jQuery 1.7) deprecated using the .on() function - http://api.jquery.com/on/
imagine this scenario:
i have several <img> elements.
$('img').bind('click', function(){...});
add some extra images (using get(), or html(), anything)
the new images don't have any binding!!
of course, since the new images didn't exist when you did the $('img')... at step 2, it didn't bind the event handler to them.
now, if you do this:
i have several <img> elements.
$('img').live('click', function(){...});
add some extra images (using get(), or html(), anything)
the new images do have the binding!!
magic? just a little. in fact jQuery binds a generic event handler to another element higher in the DOM tree (body? document? no idea) and lets the event bubble up. when it gets to the generic handler, it checks if it matches your live() events and if so, they're fired, no matter if the element was created before or after the live() call.
In adition to what they said, I think it's best to try to stick to bind when/where you can and use live only when you must.
All these jQuery methods are used for attaching events to selectors or elements. But they all are different from each other.
.bind(): This is the easiest and quick method to bind events. But the issue with bind() is that it doesn’t work for elements added dynamically that matches the same selector. bind() only attach events to the current elements not future element. Above that it also has performance issues when dealing with a large selection.
.live(): This method overcomes the disadvantage of bind(). It works for dynamically added elements or future elements. Because of its poor performance on large pages, this method is deprecated as of jQuery 1.7 and you should stop using it. Chaining is not properly supported using this method.
Find out more here
I wanted to add to this after having to debug a bit due to my own silliness. I applied .live() to a class of button on my page, assuming that it would just render out the correct ID I was trying to pass on the query string and do what I wanted to do with the ajax call. My app has dynamically added buttons associated with an inventory item. For instance, drill down categories to the 'COKE' button to add a coke to your order. Drill down from the top again, and add 'BUDLITE' - each time I wanted those items to be entered into a table via an AJAX call.
However, since I bound .live() to the entire class of buttons, it would remember each ajax call I had made and re-fire it for each subsequent button! It was a little tricky because I wasn't exactly clear on the difference between bind and live (and the answer above is crystal about it), so I figured I'd put this here just in case somebody was doing a search on this stuff.
There is a way to get the live effect but its kind of nasty.
$(this).unbind('mouseout').bind('mouseout',function(){
});
this will clear the previous and reset the new. It has seemed to work fine for me over time.
Difference between live and livequery is discussed here .
In my code, i am adding a whole set of new elements on clicking a "+"/plus button.
But the problem is, since am appending the new elements only during clicking, the elements are not responding to the jquery events.
Bellow is an event in my scenarios:
$("#form input[type='text']").blur(validateField);
This event is working for all the input element EXCEPT for the once i appended dymanically on clicking "+"/plus button.
How can i resolve it? can anyone help?
Thanks in advance.
Delegate event:
$(document.body).on('focusout',"#form input[type='text']",validateField);
As onblur event doesn't bubble by default, use onfocusout event instead.
EDIT: just checked, jquery now add delegation support for onblur event by mapping onblur event.
The blur event does not bubble in Internet Explorer. Therefore,
scripts that rely on event delegation with the blur event will not
work consistently across browsers. As of version 1.4.2, however,
jQuery works around this limitation by mapping blur to the focusout
event in its event delegation methods, .live() and .delegate().
you need to use on()
$("#form input[type='text']").on("blur",validateField);
use .on() or .live() or .delegate() method for these newly created elements. It will work.
Try with delegating the event to the static parent:
$("#form").on('blur', 'input[type="text"]', validateField);
I know of and research multiple ways to bind events .on(), .live(), .click(), etc. I know .live() is deprecated in 1.9+. The problem I'm encountering is binding dynamic DOM elements to events.
I have a div that contains links and is paginated. The links are dynamically loaded with AJAX. I want to overwrite binded events for these links so I used .unbind() and tried .on(). The problem is that these dynamically loaded links are not binded. I guess that's because the selector $('#id_of_links') is cached with the previous set of links.
QUESTION:
Is it possible to bind all elements that are loaded on the page, at any point in time, without having to set a callback when the user clicks next page on the links?
for dynamically added elements, you must bind the function to one of it's parents
$('#PARENT').on('click', '#DYNAMICALLY_ADDED_CHILD', function(){ CODE HERE });
Parent should already exist in the DOM tree...
More info on: http://api.jquery.com/on/
You cannot bind all elements, even those not loaded in the page yet, without having a callback method/function or a function that would loop in and keep checking if the elements with a specific attribute or characteristic would have the proper function binded to it, which would probably cause a memory leak over time.
I've having this weird issue where toggling the visibility of a button seems to influence how many times a click event gets called on that button.
If I use: $('button').on('click'...), to click the button only 1 click event happens as long as prior to clicking it I had done a full page load. If instead, I load a page fragment containing the button via AJAX then click the button, the on() function fires off multiple click events, an added one for every time I load the page this way.
I can limit these multiple clicks from firing by using $('button').one('click', ... But i'm wondering if this is too hack-ish and it'd be better to fix what's causing the multiple click events from firing in the first place.
Has any run into this problem before of toggling visibility -/+ AJAX page loading affecting how many click events get fired on a click handler?
I guess its not at all hack-ish coz the very first line of the jQuery Docs for One() describe the purpose this function is designed for.
Attach a handler to an event for the elements. The handler is executed
at most once per element.
This easily says that it prevents multiple raises of events.
The internal working principle of this function is also same as mentioned by #mgraph, its mentioned in the docs:
The first form of this method is identical to .bind(), except that the
handler is unbound after its first invocation. The second two forms,
introduced in jQuery 1.7, are identical to .on() except that the
handler is removed after the first time the event occurs at the
delegated element, whether the selector matched anything or not.
A bit more detail -
This method normally binds an event to a handler using .bind()/.on() and as soon as the event occurs once and only once, it unbinds the event using .unbind()/.off()
If you're loading an element via AJAX, you want to use .on()'s binding property to tie it to an element that exists when the page loads. For example, $("body").on("click", "p", ... will bind the click element to p tags not only when the page has loaded, but also after any AJAX calls. If you simply do $("p").on("click", ... this only binds the click event to p elements when the page had loaded. So in the first example, you pick a parent element (hopefully more specific than the body) of the element you want to bind to, and then specify the element within the call to .on(). So in your case you may want to try, $('body').on('click','button', ...).
Oh, and as a side note, as of jQuery 1.7, the .on() and .off() methods are preferred to attach and remove event handlers on elements over .bind() and .unbind().
This jQuery 1.3.2 code adds an element to the page, registers a "click" event, then removes and reattaches the element:
var button = $('<button>Click me!</button>')
.click(function(){ alert("Hello") })
.appendTo('body');
$('body').html('');
button.appendTo('body');
The button appears on the page as expected, but clicking on it does nothing. I would like to know why the event handlers were removed from the object.
Note: I am aware of solutions such as jQuery.live() or clone(true) or using appendTo without a removal. What I'm looking for is an explanation, not a solution or workaround.
EDIT: I suppose this could be an arbitrary and counter-intuitive design decision of the DOM. An explanation like "Because that's the way section X of specification Y wants it to be" would be fine.
When you remove an element from the DOM using jQuery, all data (including event handlers) held by jQuery on that element will be destroyed. This is done to avoid memory-leaks.
This isn't a feature (or bug) of the DOM API. It's just jQuery.
If you want your registered events to stay on your element use .detach() instead of .remove(). Use it the same way you'd use .remove(), it will keep your events on your element.