views:

37

answers:

3

Let's say I have this jQuery extension method:

$.fn.foobar = function() {
    var clone = this.parent().clone();
};

After I've gotten clone, how can I find the cloned child element that is the same as this?

Will this work?

$.fn.foobar = function() {
    var clone = this.parent().clone();
    var cloneOfThis = clone.find(this);
};

Or this?

$.fn.foobar = function() {
    var clone = this.parent().clone();
    var self = this;
    var cloneOfThis;
    clone.children().each(function() {
        var $this = $(this);
        if ($this === self) {
            cloneOfThis = $this;
        }
    });
};
+1  A: 

You can't get a reference comparison to work here because this isn't in the clone, it's the original element, it wasn't moved. An element like the one you cloned is in the cloned parent, so you have to decide what "the same" means, is it the same ID, the same HTML content, the same value?

You just need to pick a value you can compare, because the reference won't work here...you can't find something that isn't there :)

Nick Craver
+2  A: 

You could try giving it some unique class that could be used to refer back to the proper element.

$.fn.foobar = function() {
      // Add a class to "this", then clone its parent
    var clonedParent = this.addClass("someUniqueClass").parent().clone();
      // Reference the new clone of "this" inside the cloned parent,
      //   then remove the class
    var cloneOfThis = clonedParent.find(".someUniqueClass").removeClass("someUniqueClass");
      // Remove the class from the original
    this.removeClass("someUniqueClass");
};
patrick dw
A: 

Taking patrick dw's answer a little further, and incorporating Felix King's comment, I would suggest the following:

$.fn.foobar = function() {
    return $(this).each(function() {
        // Add a class to "this", then clone its parent
        var clonedParent = $(this).addClass("someUniqueClass").parent().clone();

        // Reference the new clone of "this" inside the cloned parent
        var cloneOfThis = clonedParent.find(".someUniqueClass");

        //remove the unique class to preserve the original state (other than the clone which is now present)
        $('.someUniqueClass').add(cloneOfThis).removeClass('someUniqueClass');
    });
};
Ender
Inside the `.each()`, you can't do `this.addClass`. And `$('.someUniqueClass').removeClass` wouldn't remove the class from the clones, because they're not yet part of the DOM.
patrick dw
@patrick dw - good points, thanks. I've edited my answer to reflect them.
Ender
Ender - Just remember that you're in an `.each()` loop. So if there are 50 elements, you'll be selecting `$('.someUniqueClass')` from the DOM 50 times, as well as adding the cloned item and removing the class from all of them 50 times.
patrick dw