Test of insertBefore and appendChild methods when passing between frames

The Problem

If you create a node in one frame, and then try to pass it across to another frame, you'll get an Invalid Argument error in Internet Explorer 6 when you try to appendChild or insertBefore it.

Who cares?

Why, you ask, would someone ever need to do this? Let's say that your right-hand frame loads a search page. The user searches, and then you put the results in the smaller left-hand navigation pane to allow quick access.

In order to do that, you'll have to get the data over to the other pane, and stick it in dynamically with DOM methods, unless you want to make another trip back to the server, which would suck.

Now, you're probably saying, Why not just have a function in the nav pane that looks at the document object on the content pane, and then builds the snippet there?. The problem with that is you might want to change the sort of HTML that the search returns, and then you'd have to also remember to go back and change methods in other sections of the site.

On the other hand, if you create the LI element in the content pane, and then just pass it over to the nav pane, then the nav pane's code doesn't have to worry about what sort of HTML the search is returning. You can have a function in the content pane that converts it to a nice LI that contains a UL of search result links, and then stick that LI into your table of contents nicely.

Except...

IE doesn't like it. Probably for some security reasons, you can't insertBefore or appendChild a node that was created in another frame. Nor can you manually change the ownerDocument property, or do much of anything with the node except look at it, without getting errors. Cloning the node doesn't help - that copies the ownerDocument property, which I suspect is the problem.

Mozilla seems to handle this just fine. Takes the object, appends it fine.

Workaround

Get the node from the other frame, and then create a local object. Loop through all the properties of the foriegn node, copying them into the local node. You'll have to skip over a bunch that are either read-only or inaccessible for some other reason, but you can benefit from my research and use this function:

function copyLI(src) {
  //ugly sniff, I know, but the only way to not error out!
  if(!document.all) return src;
  var myLI = document.createElement('li');
//  var j = false;
  for(var i in src) {
//    if(j) alert(i);
//    if(i=='attributes') j=true;
    if(i!='scrollHeight'&&i!='isTextEdit'
        &&i!='currentStyle'&&i!='document'
        &&i!='isMultiLine'&&i!='clientHeight'
        &&i!='scrollLeft'&&i!='parentTextEdit'
        &&i!='canHaveHTML'&&i!='isContentEditable'
        &&i!='clientWidth'&&i!='parentElement'
        &&i!='recordNumber'&&i!='scopeName'
        &&i!='tagName'&&i!='offsetWidth'
        &&i!='runtimeStyle'&&i!='filters'
        &&i!='tagUrn'&&i!='offsetLeft'
        &&i!='clientTop'&&i!='clientLeft'
        &&i!='clientRight'&&i!='clientBottom'
        &&i!='offsetRight'&&i!='offsetBottom'
        &&i!='canHaveChildren'&&i!='isDisabled'
        &&i!='behaviorUrns'&&i!='readyState'
        &&i!='all'&&i!='sourceIndex'
        &&i!='offsetHeight'&&i!='scrollWidth'
        &&i!='offsetTop'&&i!='offsetParent'
        &&i!='children'&&i!='nodeName'
        &&i!='ownerDocument'&&i!='firstChild'
        &&i!='lastChild'&&i!='childNodes'
        &&i!='nextSibling'&&i!='previousSibling'
        &&i!='parentNode'&&i!='nodeType'
        &&i!='attributes') {
      myLI.setAttribute(i,src.getAttribute(i));
    };
  };
  return myLI;
}

The commented-out stuff with j was my way of researching the problem. I had it go through and set j to true when it found the last one that had found an error. Then, it would alert each property, and when I hit an error, I put that as the trigger to start alerting and added it to the if statement.

Note: This only has been tested with LI elements, in MSIE and Mozilla, since those are the browsers that matter for my purposes, and I only need to send LI elements back and forth. There may be other properties that need to be skipped to avoid errors with other sorts of elements.

There's probably a cleaner way to work around this problem. If anyone has any ideas, let me know.

The Test

Click here to use the cleaner and add new nodes.

Click here to add new nodes without the cleaner.

  1. This is the first LI. It should get a new child LI stuck under it.
  2. This starts out as the second LI, but it should end up as the third.
  3. This starts out as the Third and last LI, but another one should get stuck under it.