Home > Mobile >  How to reorder divs with different sizes from two separate columns to one in a grid with javascript
How to reorder divs with different sizes from two separate columns to one in a grid with javascript

Time:10-06

I have a grid with two columns, and in the columns there are divs with different height and width. It is necessary to know that when we click on a div, its content toggles down (show/hide with jquery), so divs can change their heights also. For showing my contents in importance from screen view top to down, the order is in line (row). My problem is the mobile version because when I resize the page, the order will be by columns, and not as in line.

.grid {position:relative;display:flex;flex-flow:row wrap;justify-content:space-between;width:100%;max-width:1200px;margin:0 auto;padding:20px;background:grey}
.column {position:relative;display:flex;flex-flow:row wrap;align-content:start;width:49.5%;background:white}
.column1 {justify-content:right;}
.column2 {justify-content:left;}
.item {width:97.5%;max-width:720px;max-height:720px;padding:10px;color:#fff;font-size:30px}
.item1 {width:80%;height:100px;background:red}
.item2 {width:50%;height:190px;background:blue}
.item3 {width:40%;height:80px;background:green}
.item4 {width:100%;height:50px;background:yellow}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<main >
  <div >
    <div >1</div>
    <div >3</div>
  </div>
  <div >
    <div >2</div>
    <div >4</div>
  </div>
</main>

image example what I am looking for

I found a lot of questions/answers about grid and divs order but all of them are in the same columns or rows. I am still looking for a CSS or a jQuery solution.

CodePudding user response:

You can use @media only screen to set divs in one column from or to a certain width and use grid but then you will have rows same height and If you don't want this you can use js to replace childs. like this.

script.js

let item1 = document.querySelector(".item1");
let item2 = document.querySelector(".item2");
let item3 = document.querySelector(".item3");
let item4 = document.querySelector(".item4");

let doneOnce = false;
let prevWidth = false;
let widthChanged = false;

document.addEventListener("DOMContentLoaded", function () {
    width = document.body.clientWidth;
    if (width <= 600) {
        item3.replaceWith(item2);
        item4.parentElement.insertBefore(item3, item4);
    }
});

window.addEventListener("resize", () => {
    width = document.body.clientWidth;
    height = document.body.clientHeight;
    if (
        (width <= 600 && prevWidth > 600 && prevWidth) ||
        (width > 600 && prevWidth <= 600 && prevWidth)
    ) {
        doneOnce = false;
        widthChanged = true;
    }
   
    if (width <= 600 && !doneOnce && widthChanged) {
        item3.replaceWith(item2);
        item4.parentElement.insertBefore(item3, item4);
        doneOnce = true;
    } else if (width > 600 && !doneOnce && widthChanged) {
        item2.replaceWith(item3);
        item4.parentElement.insertBefore(item2, item4);
        doneOnce = true;
    }
    prevWidth = width;
});

style.css

body {
    margin: 0;
}
* {
    box-sizing: border-box;
}
.grid {
    position: relative;
    display: flex;
    flex-flow: row wrap;
    justify-content: space-between;
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
    padding: 20px;
    background: grey;
}
.column {
    position: relative;
    display: flex;
    flex-flow: row wrap;
    align-content: start;
    width: 49.5%;
    background: white;
}
.column1 {
    justify-content: right;
}
.column2 {
    justify-content: left;
}
.item {
    width: 97.5%;
    max-width: 720px;
    max-height: 720px;
    padding: 10px;
    color: #fff;
    font-size: 30px;
}
.item1 {
    width: 80%;
    height: 100px;
    background: red;
}
.item2 {
    width: 50%;
    height: 190px;
    background: blue;
}
.item3 {
    width: 40%;
    height: 80px;
    background: green;
}
.item4 {
    width: 100%;
    height: 50px;
    background: yellow;
}

@media only screen and (max-width: 600px) {
    .grid {
        flex-direction: column;
        align-items: center;
    }
    .grid > div {
        justify-content: center;
    }
}

index.html

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
 <main >
        <div >
            <div >1</div>
            <div >3</div>
        </div>
        <div >
            <div >2</div>
            <div >4</div>
        </div>
    </main>

CodePudding user response:

This is a bit of an odd request that cannot be handled with modern CSS.

I created a function that swaps the elements by inserting a marker at the desired location of object 1. There are more details on this function located in the comments of the JS.

I then created a MediaQueryList by calling the matchMedia method on the window object.

A MediaQueryList object stores information on a media query applied to a document, with support for both immediate and event-driven matching against the state of the document. - MDN

So with this said, I used an event-driven listener that is invoked by a conditional statement whenever the screen is below or equal to 1000px.

function swapElements(obj1, obj2) {
  // create marker element and insert it where object 1 is
  var mkr = document.createElement("div");
  obj1.parentNode.insertBefore(mkr, obj1);

  // move object 1 to right before object 2
  obj2.parentNode.insertBefore(obj1, obj2);

  // move object 2 to right before where object 1 used to be
  mkr.parentNode.insertBefore(obj2, mkr);

  // remove temporary marker node
  mkr.parentNode.removeChild(mkr);
}

// create function with if - else statement
function setMediaQuery(x) {
  if (x.matches) {
    swapElements(document.querySelector(".item3"), document.querySelector(".item2"));
  } else {
    swapElements(document.querySelector(".item2"), document.querySelector(".item3"));
  }
}

// create a MediaQueryListObject
const mediaQuery = window.matchMedia("(max-width: 1000px)");

// call the match function at run time
setMediaQuery(mediaQuery);

// add the match function as a listener for state changes
mediaQuery.addListener(setMediaQuery)
.grid {
  position: relative;
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
  background: grey
}

.column {
  position: relative;
  display: flex;
  flex-flow: row wrap;
  align-content: start;
  width: 49.5%;
  background: white
}

.column1 {
  justify-content: right;
}

.column2 {
  justify-content: left;
}

.item {
  width: 97.5%;
  max-width: 720px;
  max-height: 720px;
  padding: 10px;
  color: #fff;
  font-size: 30px
}

.item1 {
  width: 80%;
  height: 100px;
  background: red
}

.item2 {
  width: 50%;
  height: 190px;
  background: blue
}

.item3 {
  width: 40%;
  height: 80px;
  background: green
}

.item4 {
  width: 100%;
  height: 50px;
  background: yellow
}

@media only screen and (max-width: 1000px) {
  .column {
    width: 100%;
  }
  .column1,
  .column2 {
    justify-content: center;
  }
}
<main >
  <div >
    <div >1</div>
    <div >3</div>
  </div>
  <div >
    <div >2</div>
    <div >4</div>
  </div>
</main>

  • Related