Javascript removeChild not removing all elements inside loop

Viewed 226

What am I trying to do -

  1. Get all the elements of a particular class from DOM through javascript
  2. Get img element from parent of the element
  3. Insert img element before the parent
  4. Remove the parent element

Here is the code:

let elms = el.getElementsByClassName("my-class");
console.log(elms) // 6 elements are printed here
for (let elm of elms) {
    console.log("Inside loop") //only printed 3 times
    let elm_parent = elm.parentNode;
    let img_elm = elm_parent.getElementsByTagName("img");
    elm.parentNode.parentNode.insertBefore(img_elm[0], elm_parent);
    elm.parentNode.parentNode.removeChild(elm_parent);
} 
//Loop only executes 3 times

Here is the structure of HTML (there are total 6 such elements):

<p>
    <div style="position: relative; display: block;">
        <img src="http://something.com/image1" style="display: block;">
        <div></div><svg class="my-class" viewBox="0 0 341 102">
            <g>
                <g class="a9s-selection" style="pointer-events: none;">
                    <rect class="outer" x="-1.5" y="58" width="147" height="40"></rect>
                    <rect class="inner" x="-1.5" y="58" width="147" height="40"></rect>
                </g>
            </g>
        </svg>
    </div>
    <br>
</p>

As you can see that although elms has 6 elements, the loop is only executed 3 times. Can anyone help me understand why is this happening?

1 Answers

Problem: Call by reference of an object.

When you do el.getElementsByClassName("my-class"); it will give you a live HTMLCollection object which looks like an array. Which is handled by DOM itself. If you remove anything from the DOM which is present in HTMLCollection the length of that HTMLCollection also decreases.

Solution: Create a copy of HTMLCollection in a form of an array.

let elms = el.getElementsByClassName("my-class");
elms = Array.from(elms);
Related