7

I have a problem with this piece of code :

    var logo = document.getElementById("move_this");
    prependElement('container', logo);

    function prependElement(parentID, child) {
        parent = document.getElementById(parentID);
        parent.insertBefore(child, parent.childNodes[0]);
    }

In IE I have an error:

SCRIPT438: Object doesn't support property or method 'insertBefore'

Is there a way to resolve this problem?

Teq1
  • 631
  • 1
  • 6
  • 20
  • 1
    Searching, I found this http://stackoverflow.com/questions/5172202/does-ie7-not-fully-support-javascripts-insertbefore-method – Alfabravo Feb 21 '12 at 12:50

3 Answers3

12

Use it like that:

var parent=document.getElementById(parentID);

otherwise parent will be global, but there always is a global parent-object, the parent window(and it is read-only).

Furthermore: IE requires as 2nd argument a valid node or null, so be sure that parent has childNodes to avoid errors:

parent.insertBefore(child,(parent.hasChildNodes())
                            ? parent.childNodes[0]
                            : null);
Dr.Molle
  • 116,463
  • 16
  • 195
  • 201
  • 4
    `(parent.hasChildNodes())?parent.childNodes[0]:null` can be shortened to `parent.childNodes[0] || null` – KooiInc Feb 21 '12 at 13:12
5

insertBefore works correctly in IE as long as the 2nd parameter is a valid DOM element, or null ( typeof null is Object and so is a typeof DOM element).

For an Array, any out of bound index (which in this case is 0 as the children[] is empty) will return undefined. IE stops working in the following case as the 2nd param becomes undefined -

parent.insertBefore(child, parent.childNodes[0])
//parent.childNodes[INDEX]
//where `INDEX` is greater than parent.childNodes.length

So, a better approach for this case will be

var refEl  = parent.childNodes[INDEX] || null;
parent.insertBefore(newRowHolderNode.childNodes[0], refEl);
DDM
  • 1,099
  • 15
  • 21
0

As it was mentioned above, .insertBefore works only with valid node (explicit ID or global document reference). Local variable reference would fail:

parent.insertBefore(child, localref); //error

In IE we can use .sourceIndex property to get current global index of "marker" element, before which new child is inserted. Here is the fix for IE:

parent.insertBefore(child, document.all[localref.sourceIndex]);

It is not necessary to use .sourceIndex property, if you know exactly where in parent tree you wish to insert an element. Following properties works just fine:

parent.insertBefore(child, parent.all[1]); //must be a child
parent.insertBefore(child, parent.children[2]); //any sane index
parent.insertBefore(child, parent.firstChild); //if at least one child exists
parent.insertBefore(child, parent.lastChild); //if at least one child exists
parent.insertBefore(child, localref.nextSibling]); //if not last child
parent.insertBefore(child, localref.previousSibling]); //if not first child
  • While this code may solve the question, [including an explanation](https://meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Brian61354270 Apr 13 '20 at 17:19