#4537 closed bug (fixed)
clone(true) with namespaced events loses the namespace on the original and the clone
Reported by: | ktrott | Owned by: | jitter |
---|---|---|---|
Priority: | high | Milestone: | 1.5.1 |
Component: | manipulation | Version: | 1.5 |
Keywords: | event namespace clone | Cc: | |
Blocked by: | Blocking: |
Description
The clone(true) method does not properly preserve the namespaced events. The events are cloned but the namespace aspect of the event is lost not only on the clone but also on the original. I believe this is because the original element's event handler is reused for the clone and the handler.type is overwritten even though it already has a type on it. I believe in the clone method, before calling add event, the full type needs to be reconstructed from the type and the handler.type OR the event.add method should not overwrite handler.type but append to it?
Here is example code that should highlight the issue:
jQuery('<div id="test1">Test test test</div>').appendTo(jQuery(document.body));
jQuery("#test1").bind("click.test", function(){alert("test");});
works jQuery("#test1").trigger("click.test");
jQuery("#test1").clone(true).attr("id", "test2").appendTo(jQuery(document.body));
fails jQuery("#test1").trigger("click.foo");
works jQuery("#test1").trigger("click");
fails jQuery("#test2").trigger("click.foo");
works jQuery("#test2").trigger("click");
Change History (11)
comment:1 Changed 14 years ago by
comment:2 Changed 14 years ago by
I am also seeing this issue arise when cloning elements with plugins applied to them. The plugin uses name-spaced events and after the clone we are unable to remove the plugin using the plugin's remove event.
Any update for this issue?
comment:3 Changed 12 years ago by
This bug still exists in jquery-1.4.2. I fixed it to make it work in a local version I'm saving. Here's a diff of the changes from http://code.jquery.com/jquery-1.4.2.js:
4345c4345,4350 < jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data ); ---
var event_type = type; if((events[type][handler].namespace != null) && (events[type][handler].namespace.length > 0)) {
event_type += '.' + events[type][handler].namespace;
} jQuery.event.add( this, event_type, events[ type ][ handler ], events[ type ][ handler ].data );
comment:4 Changed 12 years ago by
Keywords: | event namespace clone added |
---|---|
Milestone: | 1.4 → 1.5 |
Owner: | set to ktrott |
Priority: | major → low |
Status: | new → pending |
Can you provide a testcase on jsFiddle so we can try and get this patch in? Thanks!
comment:6 Changed 12 years ago by
Status: | pending → closed |
---|
Automatically closed due to 14 days of inactivity.
comment:7 Changed 12 years ago by
Was this patch ever applied? It seems to have been closed automatically?
comment:8 Changed 12 years ago by
Component: | core → manipulation |
---|---|
Milestone: | 1.5 → 1.5.1 |
Priority: | low → high |
Status: | closed → reopened |
Version: | 1.3.2 → 1.5rc1 |
Doesn't look like this was fixed. As the original reporter didn't provide a test case (or did without logging in) this one slipped through the cracks because the ticket system didn't notice that was a test case attached.
comment:9 Changed 12 years ago by
Owner: | changed from ktrott to jitter |
---|---|
Status: | reopened → assigned |
comment:10 Changed 12 years ago by
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Make sure .clone(true) correctly clones namespaced events. Fixes #4537.
Changeset: 78fc79fad47ce2991c0a7148b65acd7221223eb9
comment:11 Changed 12 years ago by
Version: | 1.5rc1 → 1.5 |
---|
I messed up the example. Please ignore the first example and use this:
jQuery('<div id="test1">Test test test</div>').appendTo(jQuery(document.body));
jQuery("#test1").bind("click.test", function(){alert("test");});
works jQuery("#test1").trigger("click.test");
jQuery("#test1").clone(true).attr("id", "test2").appendTo(jQuery(document.body));
fails jQuery("#test1").trigger("click.test");
works jQuery("#test1").trigger("click");
fails jQuery("#test2").trigger("click.test");
works jQuery("#test2").trigger("click");