简体   繁体   中英

Move elements back and forth depending on screen width with JavaScript

The point of this is to move elements into another HTML container on screen resizing. So when it hits a targeted width, it moves in to the new container then, returns if it's not the target width on resize. Problem is, I can get it to work under the width but can't put them back when resizing the screen:

HTML:

<div id="target">
  <!-- move-me goes in here -->
</div>

<div id="original">
  <div class="move-me">
    <p>Stuff</p>
  </div>
  <div class="move-me">
    <p>Stuff</p>
  </div>
  <div class="move-me">
    <p>Stuff</p>
  </div>
</div>

JS:

function moveDetails() {
    let screenWidth = window.innerWidth;
    let target = document.getElementById("target");
    let origin = document.getElementById("original");
    let moveMe = document.querySelectorAll(".move-me");
    if(screenWidth <= 1100) {
        moveMe.forEach(m => {
            target.innerHTML += m.innerHTML;
            m.innerHTML = "";
        });
    } 
}
moveDetails();

I tried grabbing the "original" id then reversing it with an else, but no luck. Any help would be appreciated, vanilla JS if possible.

Update #1: Solution!

After even more digging (check out this link for a better explanation). This works on both whichever breakpoint you set, loads properly on each device and changing parent container when resizing. Still need to implement the dry version.

JS:

function moveDetails() {
    /*
    Call your targets, both inner width and client width finally, set break point
    */
    let target = document.getElementById("target"),
            origin = document.getElementById("original"),
            moveMe = document.querySelectorAll(".move-me"),
            breakPoint = 1100,
            viewportWidth = window.innerWidth || document.documentElement.clientWidth;
    /*
    This is for anything below the breakpoint on refersh so the changes immediately show.
    We'll use the method "appendChild()" throughout on the parent elements.
    */      
    if (viewportWidth < breakPoint) {
        moveMe.forEach(m => {
            target.appendChild(m);
        });
    }
    /*
    addEventListener of 'resize' so it will add/remove elements with the
    given class name to the targeted ids/parents
    */
    window.addEventListener('resize', () => {
        let viewportWidth = window.innerWidth || document.documentElement.clientWidth;
        if (viewportWidth < breakPoint) {
            moveMe.forEach(m => {
                target.appendChild(m);
            });
        } else {
            moveMe.forEach(m => {
                origin.appendChild(m);
            });
        }
    });
}
moveDetails();

To also note, this is great for grabbing specific class named elements. Most methods I came across would select EVERY child element. So, if you need to grab something specific, hopefully this would help.

Does it work as expected inside of a resize event handler?

  document.addEventListener('resize', () => {
        let screenWidth = window.innerWidth;
        let target = document.getElementById("target");
        let origin = document.getElementById("original");
        let moveMe = document.querySelectorAll(".move-me");
        if(screenWidth <= 1100) {
            moveMe.forEach(m => {
                target.innerHTML += m.innerHTML;
                m.innerHTML = "";
            });
       } 
  });

You need to add an else statement, as at the moment, you are only doing something when the width is less than or equal to 1100.

Have also updated your variables to use const rather than let, as they are not being reassigned.

function moveDetails() {
    const screenWidth = window.innerWidth;
    const target = document.getElementById("target");
    const origin = document.getElementById("original");
    const moveMe = document.querySelectorAll(".move-me");
    if(screenWidth <= 1100) {
        moveMe.forEach(m => {
            target.innerHTML += m.innerHTML;
            m.innerHTML = "";
        });
    } else { // your code here }
}
moveDetails();

Update #1: Solution!

After even more digging (check out this link for a better explanation). This works on both whichever breakpoint you set, loads properly on each device and changing parent container when resizing. Still need to implement the dry version.

JS:

function moveDetails() {
    /*
    Call your targets, both inner width and client width finally, set break point
    */
    let target = document.getElementById("target"),
            origin = document.getElementById("original"),
            moveMe = document.querySelectorAll(".move-me"),
            breakPoint = 1100,
            viewportWidth = window.innerWidth || document.documentElement.clientWidth;
    /*
    This is for anything below the breakpoint on refersh so the changes immediately show.
    We'll use the method "appendChild()" throughout on the parent elements.
    */      
    if (viewportWidth < breakPoint) {
        moveMe.forEach(m => {
            target.appendChild(m);
        });
    }
    /*
    addEventListener of 'resize' so it will add/remove elements with the
    given class name to the targeted ids/parents
    */
    window.addEventListener('resize', () => {
        let viewportWidth = window.innerWidth || document.documentElement.clientWidth;
        if (viewportWidth < breakPoint) {
            moveMe.forEach(m => {
                target.appendChild(m);
            });
        } else {
            moveMe.forEach(m => {
                origin.appendChild(m);
            });
        }
    });
}
moveDetails();

To also note, this is great for grabbing specific class named elements. Most methods I came across would select EVERY child element. So, if you need to grab something specific, hopefully this would help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM