views:

1847

answers:

3

I'm using the Fish Gadget (http://abowman.com/google-modules/fish/) within a wiki based CMS, and need to reposition the gadget from one HTML element to another. (Note: the fish gadget is an example -- the problem occurs with other gadgets as well.)

If I directly reposition the gadget using the gadgets base class "ig_reset", then everything works. If I try to reposition using a surrounding wrapper, then the iframe used by the gadget seems to take over. Unfortunately I need the flexibility of repositioning using the surrounding wrapper.

This seems to have something to do with moving a SCRIPT tag around in the DOM. The gadget dynamically creates a script and a style tag. If I remove the dynamically created script tag from the DOM, and then reposition the wrapper to another location in the DOM, all works well. If I try to move the script tag to another DOM element then the original problem occurs. So moving a script tag around the DOM seems to be the cause -- regardless of when the move occurs (even post-load).

I'd like to understand what is happening here to cause the frame to take over the page, and also find a better solution than removing the dynamically created script tag.

I put a test up here: http://solidgone.com/jquery/google-gadget.html -- the demo uses jQuery, but I don't think this is related to jQuery...

+8  A: 

Whenever you append a script element into a page, using jQuery, it will attempt to execute it. Thus when you move ig_reset (which is only a table - no script) it works without issue. When you try to move the wrapper - which contains the script - the script is moved and re-executed.

We're working to fix this re-execution issue in jQuery core but for the time being that's what is going on here.

John Resig
+4  A: 

As John Resig notes, this is a jQuery issue. You can verify this by replacing your handler

$("#with-wrapper").click(function () 
{
   $('.sidebar-content-wrapper').contents().appendTo($("#sidebar"));
});

with one that avoids using the jQuery methods to actually move each element:

$("#with-wrapper").click(function() 
{
   var sidebar = $("#sidebar")[0];
   $('.sidebar-content-wrapper').contents().each(function()
   { 
      // raw DOM method rather than jQuery's 
      //  appendTo() -> domManip() -> execute script blocks behavior
      sidebar.appendChild(this);
   });
});
Shog9
Thanks for the added insight.
DaveG
I see it copies the DOM, not moving it
vsync
@vsync: why would you say that?
Shog9
I see it copying elements (each loop) but whats happens after?I'de expect do kill the original element, no ?
vsync
@vsync: there's no element copying going on here. See: https://developer.mozilla.org/En/DOM/Node.appendChild
Shog9
A: 

Hi,

I've run into this issue myself with some JavaScript code executing when moving a DOM element (driving me nuts!). I didn't have much success with Shog9's code. It still executed even if I use JavaScript's appendChild() so it seems more of a JS issue than a jQuery issue.

Any ideas?