I am trying to copy a div content from one place to another, for this I am using something like:
$('#newDiv').html($('#oldDiv').html());
The problem is that some child elements have events attached using the bind() jquery method. I would want to copy also those events to the new location.
Any idea about a way to do this "event copy"?
Description
You create dynamic content in the moment you copy the content.
You need jQuery .live() or delegate() method to bind events to dynamically created html.
Choose .live() or delegate() 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.
.delegate() Available since jQuery 1.4.2. 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.
Check out my sample and this jsFiddle Demonstration
Sample
<div id="newDiv"></div>
<div id="oldDiv"><a>click me</a></div>
$("a").live("click",function() {
alert("click");
});
// copy content
$('#newDiv').html($('#oldDiv').html());
More Information
jQuery.live()
jQuery.delegate()
jsFiddle Demonstration
If you use the jquery Clone method you can set a parameter specifying if you want to keep events or not... check out: http://api.jquery.com/clone/
It should do nicely.
Related
$(".hovertip").parent().live('hover', function() {
...
The above code doesn't seem to register.
This doesn't seem to work either:
$(".hovertip").parent().live({
mouseenter:
function() {
...
Any examples of .live, .delegate, .bind, or .on working with a jQuery selector and a .parent() selector with .hover() or mouseenter: and mouseleave:?
Update: I've created a separate question to address the dynamic DOM issue this Question has raised: jQuery .on() with a .parent() and dynamic selector
Try:
$(".hovertip").parent().on('hover', function() {
alert('yay');
});
Note: .on was introduced in jQuery 1.8.
Working demo http://jsfiddle.net/pRB8n/ Hover over test test - in the demo
If you really want to use .delegate try this please: http://jsfiddle.net/TURBX/2/ - http://api.jquery.com/delegate/
Delegate
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.
Hope rest fits the needs :)
P.S. - .live is deprecated: for further if you keen - my old post here: :) What's wrong with the jQuery live method?
under category you will see: http://api.jquery.com/live/ "deprecated"
I would add a comment to Tats_innit's post, but I can't.
As per the documentation on live,
Chaining methods is not supported. For example, $("a").find(".offsite, .external").live( ... ); is not valid and does not work as expected.
That's why .parent() does not work.
Binding to parent
Event delegation (handled by the deprecated live and .delegate, and now by .on/.one) only moves downwards. You can't have an upward event delegation like you seem to want to do here.
That is to say if the parent of ".hovertip" does not exist then clearly ".hovertip" does not exist so you are actually binding to nothing.
If your goal is to bind the event to the parent of ".hovertip" when it appears, then you're SOL since delegation only moves downwards (to descendants).
Your options to handle that would be:
* Bind to the parent of .hovertip when it is appended to the DOM.
* Know a selector for the parent of .hovertip ahead of time and bind to it immediately, perhaps through delegation.
Delegating to child
If your goal is to have the event fire when .hovertip is hovered, but .hovertip may not be in the DOM and its parent is not known, you must use a method like this:
$("known parent selector of .hovertip").on('hover', '.hovertip', function () {
"known parent selector of .hovertip" has to be an element that you know ahead of time. If you can't know, you have to use document, but I'd suggest to try to get as close as possible. You can only use this on elements that exist in the DOM at the time of binding.
I think what you are looking for, actually, is something along these lines:
$(document).on('mouseover', '.hovertip', function() {
// handle your mouseover changes, here
});
$(document).on('mouseout', '.hovertip', function() {
// handle your mouseout changes, here
});
.live, .bind, are all deprecated, AFAIK, which means they'll go away in the future, and you might not want to rely on their continued support.
It would also be far better to replace $(document) with a selector that's closer to your .hovertip elements, but above them in the DOM nesting, so they can respond to your event, but without forcing jQuery to watch for every event on every element in the whole document. I simply put document in there as an example, as I don't know what the rest of your structure looks like.
http://jsfiddle.net/mori57/qa7py/
As I think about it, I think it's worth pointing out that throwing things to .parent() may not always work out the way you expect, especially if you're modifying the DOM. I think it's far safer to set a higher-level event handler.
If you must use something like the .parent(), I always found more accurate results with .closest(), and giving it a selector also helps the parsing engine narrow its search. You don't want one parent triggering the hover state for /all/ the .hovertips at one time, which could happen in some cases.
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
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.
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.
Is it possible to clone event from one element, to another.
For example:
$('.somelink').click({data:data},somefunc);
I need event in another place in document for element with different class.
You can pass multiple selectors to $(), separating them by comma. Like this:
$('.somelink, .some-otherlink, #third-id').live('click', {data:data}, somefunc);
Now they all share the same click event
The jQuery .clone() function has an optional withDataAndEvents argument which will copy the node itself, all attached events and any inline data.
See http://api.jquery.com/clone/ for more details.
Extending on #moe's answer. Use .live() to bind events to elements even if they are not in the DOM. They will be bound as soon as they exist.
$('.somelink, .some-otherlink, #third-id').live('click',{data:data},somefunc);
To copy it, you can do:
$('.somelink').click( $('.otherlink').attr('onclick') );