#351 ✓not_for_core
ronin-28987 (at lighthouseapp)

New swap method for elements

Reported by ronin-28987 (at lighthouseapp) | September 20th, 2008 @ 12:38 PM | in 1.7


var swapMethod = {
	swap: function(element, el) {
		element = $(element);
		el = $(el);

		if (element == el) return element;

		var clone = el.cloneNode(false); // no need to clone deep
		Element.replace(element, clone);
		Element.replace(el, element);
		Element.replace(clone, el); // make sure references (like event observers) are kept
		return element;
	}
}
Element.addMethods(swapMethod);

now


$("foo").swap($("bar"));

will swap foo and bar, so foo is in the place where bar was and bar where foo was

Comments and changes to this ticket

  • Juriy Zaytsev

    Juriy Zaytsev September 20th, 2008 @ 06:09 PM

    • Assigned user set to “Juriy Zaytsev”
    • State changed from “new” to “enhancement”
    • Tag changed from dom, element, enhancement, needs_docs, needs_tests to dom, element, enhancement, needs_docs, needs_patch, needs_tests
    • Milestone set to 1.7

    Hi, Giso.

    I think cloneNode, while being short and convenient, is a little too obtrusive in this case:

    1) By replacing an element with its clone, you discard all of its event handlers.

    2) You also loose references to the original element (that might have been created before method was invoked).

    Both of these "deficiencies" could be worked around by introducing a temporary element:

    
    Element.addMethods({
      swapWith: function(element, other) {
        element = $(element);
        other = $(other);
        if (element !== other) {
          var stub = document.createElement('div');
          other = Element.replace(other, stub);
          element = Element.replace(element, other);
          stub = Element.replace(stub, element);
          stub = null; // prevent possible leaks
        }
        return element;
      }
    });
    

    Marking as an enhancement.

  • ronin-28987 (at lighthouseapp)

    ronin-28987 (at lighthouseapp) September 20th, 2008 @ 08:10 PM

    
    
    var ref1 = $("header");
    var ref2 = $("footer");
    
    ref1.observe("click", function(){console.log("header clicked (swapWith)")});
    ref2.observe("click", function(){console.log("footer clicked (swapWith)")});
    
    console.time("swapWith");
    for (i = 0; i < 1000; i++)
    $("header").swapWith("footer");
    console.timeEnd("swapWith"); // approx 4200 ms
    
    console.log(ref1, ref2); // reference not lost
    // both click observers still fired
    
    // ----
    
    var ref1 = $("header");
    var ref2 = $("footer");
    
    ref1.observe("click", function(){console.log("header clicked (swap)")});
    ref2.observe("click", function(){console.log("footer clicked (swap)")});
    
    console.time("swap");
    for (i = 0; i < 1000; i++)
    $("header").swap("footer");
    console.timeEnd("swap"); //  approx 4250 ms
    
    console.log(ref1, ref2); // reference not lost
    // both click observers still fired
    
    

    so yours is a bit quicker (which is also good ofcourse)

  • John-David Dalton
  • Tobie Langel

    Tobie Langel September 23rd, 2008 @ 07:49 PM

    That's too app specific imho. I'd suggest closing this as not for core.

  • ronin-28987 (at lighthouseapp)

    ronin-28987 (at lighthouseapp) September 23rd, 2008 @ 08:52 PM

    I wonder what's app specific about being able to swap nodes in a convenient way.

    I didn't came up with the idea because of any app anyway.

    
    <div>
       <div id="header">header</div>
       <div id="content">content</div>
       <div id="footer">footer</div>
    </div>
    
    

    $("footer") doesn't have a nextSibling

  • Juriy Zaytsev

    Juriy Zaytsev September 23rd, 2008 @ 09:56 PM

    I, personally, have never needed such functionality, but I wouldn't say it's app-specific.

    I think, this is something that would be a perfect fit for an official prototype.js add-on.

    Would someone volunteer to write unit tests?

  • John-David Dalton
  • ronin-28987 (at lighthouseapp)

    ronin-28987 (at lighthouseapp) September 23rd, 2008 @ 10:42 PM

    @Juriy If possible I volunteer to write unit tests, but after 3rd of October, because don't have time before.

    @John-David Didn't know that, that's nice

  • Tobie Langel

    Tobie Langel September 24th, 2008 @ 10:59 AM

    • State changed from “enhancement” to “not_for_core”

    @kangax: The fact that you have to build a complex and less-performant solution to handle edge cases, coupled with the fact that you admit not ever having had a usecase for it should raise a flag.

    Definitely better fit as an add-on.

  • ronin-28987 (at lighthouseapp)

    ronin-28987 (at lighthouseapp) September 24th, 2008 @ 11:15 AM

    Can you explain me what is meant with an "add-on" in this case?

    The prototype website doesn't offer any add-ons, or I didn't find them.

  • John-David Dalton
  • Juriy Zaytsev
  • Tobie Langel

    Tobie Langel July 24th, 2009 @ 02:10 AM

    • Tag changed from dom, element, enhancement, needs_docs, needs_patch, needs_tests to element, needs_docs, needs_patch, needs_tests, section:dom

    [not-tagged:"dom" tagged:"section:dom" bulk edit command]

  • Tobie Langel

    Tobie Langel July 24th, 2009 @ 02:11 AM

    • Tag changed from element, needs_docs, needs_patch, needs_tests, section:dom to needs_docs, needs_patch, needs_tests, section:dom

    [not-tagged:"element" bulk edit command]

  • Tobie Langel

    Tobie Langel July 24th, 2009 @ 02:25 AM

    • Tag changed from needs_docs, needs_patch, needs_tests, section:dom to missing:documentation, needs_patch, needs_tests, section:dom

    [not-tagged:"needs_docs" tagged:"missing:documentation" bulk edit command]

  • Tobie Langel

    Tobie Langel July 24th, 2009 @ 02:26 AM

    • Tag changed from missing:documentation, needs_patch, needs_tests, section:dom to missing:documentation, missing:tests, needs_patch, section:dom

    [not-tagged:"needs_tests" tagged:"missing:tests" bulk edit command]

  • Tobie Langel

    Tobie Langel July 24th, 2009 @ 02:28 AM

    • Tag changed from missing:documentation, missing:tests, needs_patch, section:dom to missing:documentation, missing:patch, missing:tests, section:dom

    [not-tagged:"needs_patch" tagged:"missing:patch" bulk edit command]

  • Tobie Langel

    Tobie Langel July 24th, 2009 @ 03:36 AM

    • Tag changed from missing:documentation, missing:patch, missing:tests, section:dom to missing:documentation, missing:patch, needs:tests, section:dom

    [not-tagged:"missing:tests" tagged:"needs:tests" bulk edit command]

  • Tobie Langel

    Tobie Langel July 24th, 2009 @ 03:37 AM

    • Tag changed from missing:documentation, missing:patch, needs:tests, section:dom to missing:documentation, needs:patch, needs:tests, section:dom

    [not-tagged:"missing:patch" tagged:"needs:patch" bulk edit command]

  • Tobie Langel

    Tobie Langel July 24th, 2009 @ 03:38 AM

    • Tag changed from missing:documentation, needs:patch, needs:tests, section:dom to needs:doc, needs:patch, needs:tests, section:dom

    [not-tagged:"missing:documentation" tagged:"needs:doc" bulk edit command]

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

The Prototype JavaScript library.

Shared Ticket Bins

People watching this ticket

Pages