Skip to content

I need to move a node list from one parent to another

I’m trying to move a node list (in my case img HTML tags with a class name of “.images”) when I reach a specific breakpoint to another parent as the first child of that new parent.

/* BEFORE BREAKPOINT */
<div class="old-parent">
   <img class="images">
   <div class="new-parent">
   </div>
</div>

<div class="old-parent">
   <img class="images">
   <div class="new-parent">
   </div>

</div>

<div class="old-parent">
   <img class="images">
   <div class="new-parent">
   </div>
</div>
/*AFTER REACHING THE BREAKPOINT*/

<div class="old-parent">
   <div class="new-parent">
     <img class="images">
   </div>
</div>

<div class="old-parent">
   <div class="new-parent">
     <img class="images">
   </div>
</div>

<div class="old-parent">
   <div class="new-parent">
     <img class="images">
   </div>
</div>

So far is working when I use a single selector, however when I try to select them all and transfer them to a new parent is not working.

const newParent = document.querySelectorAll('.new-parent');
const images = document.querySelectorAll('.images');
const mediaQ = window.matchMedia('(max-width: 494px)');

const changeImg = (e) => {
    if (e.matches) {
        newParent.forEach(elem => {
            elem.insertBefore(images, elem.childNodes[0]);
        })
    }
};

mediaQ.addEventListener('change', changeImg);

Then returns an error in the console:

Uncaught TypeError: Failed to execute ‘insertBefore’ on ‘Node’: parameter 1 is not of type ‘Node’

Answer

You need to index images to move one image at a time.

const changeImg = (e, i) => {
    if (e.matches) {
        newParent.forEach(elem => {
            elem.insertBefore(images[i], elem.childNodes[0]);
        })
    }
};