0

The issue is similar to the one described here, as far as I can tell. However, I am not using mootools and my question and results are different. This is a test page to demonstrate the issue: http://jsfiddle.net/S7rtU/2/.

I add elements to a container using createElement and appendChild. As I add each, I also store a reference to it in a private array (elems).

Then, I decide to clear the container, and do so by setting container.innerHTML = ''.

(In my example, I set it first to a pending message, and then 3s later, using setTimeout, I clear it. This is to give time to observe the changes to the DOM.)

Then, I try to repopulate the container from the elems array, calling container.appendChild for each of the stored elements.

I have tested on the browsers I have at hand: Firefox 17.0.1, Chrome 23.0.1271.97, Safari 3.1.2, IE 6 and IE 7. All except IE 6 & 7 will actually restore those elements. So they are successfully stored in memory and references not destroyed. Furthermore, the event handlers registered to those elements still work.

In IE, the elements do not reappear.

What I have read about this issue, including the other SO question, seem to suggest that references are supposed to be broken when you modify innerHTML on the container. Event handlers are also supposed to be broken. However the 3 modern browsers I tested do not break the references, nor the event handlers.

Of course, to make this work in IE I can use something like this, but this is significant extra processing if there are lots of elements:

function explicitClearContainer() {
    var e;
    // Explicitly remove all elements
    for (var i = 0; i < elems.length; ++i) {
        e = elems[i];
        // Update the reference to the removed Node
        elems[i] = e.parentNode.removeChild(e);
    }
}

My question is what is known about this behaviour, what can be expected in different environments, what are the pitfalls of using this sort of technique?

I would appreciate any comments.

Community
  • 1
  • 1
ejm
  • 782
  • 7
  • 16
  • i expect 1. you won't use innerHTML again, except for inserting arbitrary (origin considered secure) html, and 2. to not use IE ;) – metadings Jan 15 '13 at 02:01
  • @metadings—the OP is likely not coding solely for his/her own use, but for a web site that might be visited by many people, some of whom may be using IE 6 or 7 (perhaps 5% or so). – RobG Jan 15 '13 at 02:09

1 Answers1

0

The innerHTML property was only "standardised" in HTML5, which really just documents common browser behaviour for many features. Things such as innerHTML have been implemented differently in different browsers and will continue to be different for some time, so best to avoid using it if it's causing problems.

There are other approaches to clearing the child nodes of an element, e.g.:

function removeContent(element) {
  while (element.firstChild) {
    element.removeChild(element.firstChild);
  }
}

Which should avoid your issues with innerHTML and is a bit less code than your version. You can also replace element with a shallow clone of itself, but that may cause other issues.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • Thanks for your answer - avoiding innerHTML is definitely a cross-browser way to go. – ejm Jan 15 '13 at 02:14