4

jQuery's clone function looks like this:

.clone( [withDataAndEvents ] [, deepWithDataAndEvents ] )

withDataAndEvents: A Boolean indicating whether event handlers and data should be copied along with the elements.

deepWithDataAndEvents: A Boolean indicating whether event handlers and data for all children of the cloned element should be copied.

Both of these parameters affect data and events. Would it be possible to keep only the data, but not the events? Basically, my ideal clone function would look like this:

.idealClone( [withData] [, withEvents ] [, deepWithData ] [, deepWithEvents ] )

withData: A Boolean indicating whether data should be copied along with the elements.

withEvents: A Boolean indicating whether event handlers should be copied along with the elements.

deepWithData: A Boolean indicating whether data for all children of the cloned element should be copied.

deepWithEvents: A Boolean indicating whether event handlers for all children of the cloned element should be copied.

Is there any way to acheive this?

NB I'm working with 1.8.1, but answers for all version are welcome

Shawn
  • 10,931
  • 18
  • 81
  • 126

1 Answers1

3

You can easily extend the jQuery object with your ideal clone method, and use various combinations of data and off to keep only the things you want. Personally I think it's easy enough to just do:

// clones with data and events, then unbinds all events (bound with .on)
$(element).clone(true).off();
nbrooks
  • 18,126
  • 5
  • 54
  • 66
  • Won't that only remove those bound with `on()`? – BenM Feb 14 '13 at 22:35
  • @Ben Yes I believe so, thanks for the clarification. I haven't tried, but the docs suggest so. – nbrooks Feb 14 '13 at 22:37
  • All events are attached with `.on()` in the newer jQuery versions (I think >= 1.7). For example using `.click(handler)` is a shortcut for using `.on('click', handler)`, therefore, unless some method was attached using the deprecated `.bind()`, using `.off()` should be fine! – jpatiaga Feb 14 '13 at 22:55
  • I tried that, but where `$(element).clone(true, true)` works fine, using `$(element).clone(true, true).off()` gives me an error: `Uncaught TypeError: Object # has no method 'off'`. – Shawn Feb 15 '13 at 15:29
  • 1
    @Shawn Be careful with your jQuery versions: [`off`](http://api.jquery.com/off) wasn't added til jQuery 1.7, so in earlier versions that error would be expected. You probably tested with different versions, causing the difficulty with reproducing it. – nbrooks Feb 15 '13 at 16:20
  • No, I'm using 1.8.1 in my own code and 1.8.3 in jsfiddle for testing. Both should have `off`. – Shawn Feb 15 '13 at 16:23
  • Ok, I double-checked and even though I downloaded jquery 1.8.1, Drupal forces the use of 1.4.4. In this case, can I simply use `unbind()` and expect the same result? – Shawn Feb 15 '13 at 16:48
  • @Shawn Event-handling was a lot more fragmented in the older versions (hence the transition to the unified api with `on`/`off` in newer versions). If there's no way to change versions, I would say just be careful about what kind of event handling code you use: for `delegate`, you use `undelegate`; for `live`, you use `die`; for `bind`, you use `unbind`. So, the simple answer is you have to undo whatever your specific code does :) – nbrooks Feb 15 '13 at 17:26