Picture from — bing wallpaper, if there is infringement, contact delete

Recently, I wanted to develop a small program by myself, but because it was my own idea and I did not want to pay others to design the page view, so I visited some websites and public accounts about App design, and there was a design layout — waterfall flow layout, when I saw it, I was attracted by it. I think we have all seen it, such as the commodity list page of e-commerce App.

Well, without further ado, let’s get started.

First, the structure and style of the page are as follows:

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta < span style> * {margin: 0; max-width: 100%; padding: 0; } .wrapper { width: 900px; height: 900px; Background-color: rgba(200, 200, 200, 0.3); margin: 12px auto; position: relative; overflow-y: auto; } .wrapper::-webkit-scrollbar { display: none; } .img { margin: 6px; border-radius: 6px; overflow: hidden; Background - image: url (https://img0.baidu.com/it/u=3898438129, 1463014098 & FM = 26 & FMT = auto&gp = 0. JPG); background-repeat: no-repeat; position: absolute; } </style> </head> <body> <div class="wrapper"></div> </body> </html>Copy the code

The renderings are so plain:

With that done, let’s write the JS code

// Get the container
const wrapper = document.querySelector('.wrapper');
// The height array of the element container
const img_height = [120.180.300];
// Width of the image
const img_width = 288;
// The height array for each column
const img_height_arrs = [];
/ / the number of columns
const col = Math.floor(wrapper.offsetWidth / img_width);
// Initialize the height of each column
for (let i = 0; i < col; i++) {
    img_height_arrs[i] = 0;
}
Copy the code

Follow my steps through the code above, and the initialization is done.

Now let’s add elements to our container

// Instead of sending a network request for image data, use the for loop to simulate it
for (let i = 0; i < 30; i++) {
    // Create the corresponding div according to the number of data,
    let div = document.createElement('div');
    // Get the height randomly
    let height = img_height[Math.floor(Math.random() * i % 3)] + 'px';
    div.className = 'img';
    div.style.width = img_width + 'px';
    div.style.height = height;
    wrapper.appendChild(div);
}
Copy the code

Now let’s look at the renderings:

!!!!!!!!! What’s going on here?

This is because we set the position of divs to absolute and did not assign the correct left and top values to them.

Now let’s change the code snippet in the for loop to return the div inside the container to its proper position

for (let i = 0; i < 30; i++) {
    // Create the corresponding div according to the number of data,
    let div = document.createElement('div');
    // Get the height randomly
    let height = img_height[Math.floor(Math.random() * i % 3)] + 'px';
    // Get the index with the minimum height
    let min_index = img_height_arrs.indexOf(Math.min.apply(null, img_height_arrs));
    div.className = 'img';
    div.style.width = img_width + 'px';
    div.style.height = height;
    // The top value of this div depends on the current minimum height
    div.style.top = img_height_arrs[min_index] + 'px';
    // The current left value is the minimum height index * (element height + 12).
    div.style.left = min_index * (img_width + 12) + 'px';
    // Now we add the minimum height value to the height of the current element plus 12
    img_height_arrs[min_index] += parseInt(height) + 12;
    // Add all divs to the wrapper
    wrapper.appendChild(div);
}
Copy the code

Effect GIF:

Isn’t it very simple ~, the complete code is as follows:

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta < span style> * {margin: 0; max-width: 100%; padding: 0; } .wrapper { width: 900px; height: 900px; Background-color: rgba(200, 200, 200, 0.3); margin: 12px auto; position: relative; overflow-y: auto; } .wrapper::-webkit-scrollbar { display: none; } .img { margin: 6px; border-radius: 6px; overflow: hidden; Background - image: url (https://img0.baidu.com/it/u=3898438129, 1463014098 & FM = 26 & FMT = auto&gp = 0. JPG); background-repeat: no-repeat; position: absolute; } </style> </head> <body> <div class="wrapper"></div> <script> // get container const wrapper = document.querySelector('.wrapper'); // Element container height array const img_height = [120, 180, 300]; // Image width const img_width = 288; // Array height of each column const img_height_arrs = []; // Column count const col = math.floor (wrapper.offsetwidth/img_width); // initialize each column height for (let I = 0; i < col; i++) { img_height_arrs[i] = 0; } for (let i = 0; i < 30; I++) {// create a corresponding div, let div = document.createelement ('div'); Let height = img_height[math.floor (math.random () * I % 3)] + 'px'; Let min_index = img_height_arrs.indexof (math.min. apply(null, img_height_arrs)); div.className = 'img'; div.style.width = img_width + 'px'; div.style.height = height; Div. Style. top = img_height_arrs[min_index] + 'px'; Div. Style. left = min_index * (img_width + 12) + 'px'; // Now we add the minimum height to the current element height plus 12 img_height_arrs[min_index] += parseInt(height) + 12; // Add all divs to the wrapper. Wrapper. AppendChild (div); } </script> </body> </html>Copy the code

A simple waterfall flow, just like that