13

I have two divs for different sections of my webpage, a working and a reference section. One is fixed size, the other is variable sized and they are vertically stacked. I am trying to design it so that if you want to work on something in the reference pane, you click a link and it swaps all the data between the two panes. My idea was to do the following:

var working = $("#working_pane").html();
var ref = $("#reference_pane").html();

$("#working_pane").html(ref);
$("#reference_pane").html(working);

The problem with this, is it seems that any javascript referenced inside of these panes (for example, in place editors) get broken upon switching. No javascript errors occur, it's just that nothing happens, like the javascript ties are broken.

Is there any to move the html without breaking the javascript contained?

KallDrexx
  • 27,229
  • 33
  • 143
  • 254
  • It might be easier to exchange the positions (and/or css class) of the two div's, rather than trying to move their contents around. – Seth May 08 '10 at 00:13
  • The only way I see to do this, since both panes are vertically stacked, is to absolutely position the divs, but this makes it annoying if I modify the master page/template for the page as a whole. Then I have to modify the div's positions every time I change the main page. – KallDrexx May 08 '10 at 00:27

2 Answers2

29

When you are working with bits of an HTML document, you should aim to work with the Node objects that are the content as the browser sees it, not HTML strings.

To get HTML the browser has to look at the Nodes and serialise them to a string. Then when you assign that HTML to another part of the document (with innerHTML or jQuery html(...)), you are telling the browser to destroy all the content that was previously in the element, laboriously parse the HTML string back into a new set of Node objects, and insert these new Nodes into the element.

This is slow, wasteful, and loses any aspect of the original Node objects that can't be expressed in serialised HTML, such as:

  • event handler functions/listeners (which is why your editors are breaking)
  • variable references other JavaScript code has to the Nodes (also breaks scripts)
  • form field values (except, partially, in IE due to a bug)
  • custom properties

So — and this applies whether you're using jQuery or the plain DOM — don't throw HTML around! Take the original node objects and insert them into the place you want them (they'll leave the place they originally were automatically). The references stay intact so scripts will keep working.

// contents() gives you a list of element and text node children
var working = $("#working_pane").contents();
var ref = $("#reference_pane").contents();

// append can be given a list of nodes to append instead of HTML text
$("#working_pane").append(ref);
$("#reference_pane").append(working);
bobince
  • 528,062
  • 107
  • 651
  • 834
0

This could be happening maybe as a result of duplicate ids. basically you may have element a in a div which has the id=id1 now this gets stored in a var and gets injected into a new div. now currently seems you have no mechanism for making sure you do not have duplicate ids at the same time. this can break js

So look into this and if you do make sure elements are first stored in a var then the originals are removed and then appended into a new location.

makeitmorehuman
  • 11,287
  • 3
  • 52
  • 76
  • I tried adding 2 lines prior to the html() calls to .empty(). Same thing still happens. Inspecting the elements via the chrome dev tools show the tags having the correct IDs. – KallDrexx May 08 '10 at 00:25