SoFunction
Updated on 2025-03-01

Implementing waterfall flow effect based on JavaScript (cyclic asymptotic)

1. Create an Html template

The idea is to first use a div container to host all the content, then div box is used to place pictures, and finally div box_border is used as the picture box, the code is as follows

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Waterfall flow</title>
</head>
<body>
<div class="container" >
<div class="box_border" >

<div class="box" >
<img src="image/">
</div>
<!--BundleBoxCopy multiple copies,This is because the code is repeated-->
</div>
</div>
</body>
</html>

2. Simple style setting through css

Mainly set horizontal placement, frame color, border and so on

/*
 No blank border, black and gray background
 */
body{
margin: 0px;
background: darkgray;
}
/*
 The total layout is set to relative layout
 */
.container{
position: relative;
}
/*
 Set box properties
 */
.box{
padding: 5px;
float: left;
}
/*Set picture border shadow and rounded corner
 */
.box_border{
padding: 5px;
border: 1px solid #cccccc;
box-shadow: 0px 0px 5px #ccc;
border-radius: 5px;
}
/*Set picture format*/
.box_border img{
width: 150px;
height: auto;
}

Control the number of pictures placed in each row

After the above css layout, the browser window size will change, and the number of pictures inside will also change. Now you need to use JS to fix the number of pictures in each row, which can achieve good results for screens of different sizes.

/*
 Used to load other functions
 */
 = function(){
setImgLocation("container");
}
/*
 Set the number of pictures
 */
function setImgLocation(parent){
var cparent = (parent);//Get the parent nodevar childArray = getChildNodes(cparent);//Get the number of picturesvar imgWidth = childArray[0].offsetWidth;//Get photo widthvar screenWidth = ;//Get the browser widthvar count = (screenWidth/imgWidth);//Number of each row = "width:"+count*imgWidth+"px;margin: 0 auto;";//Set its width and center
}
/*
 Get the number of all pictures
 */
function getChildNodes(parent){
var childArray =[];//Define an array to store image boxvar tempNodes = ("*");//Get all nodes under the parent node//Loop to add the node with class as boxfor(var i = 0;i<;i++){
if(tempNodes[i].className == "box"){
(tempNodes[i]);
}
}
return childArray;//Return all child nodes}

The renderings: The number of displays for different screen sizes is different

Implement static waterfall flow

First realize the static layout, that is, the browser pull-down will not automatically refresh new pictures.

Implementing an arrangement algorithm is very simple

1. Save all the heights of the first row of pictures to an array
2. Calculate the minimum height and corresponding position of the pictures in the first row
3. Put the first picture after the first row in this position
4. Reset the height of this position to add up the two pictures
5. Loop 2 All remaining pictures

Code:

/*
 Used to load other functions
 */
 = function(){
setImgLocation("container");
}
/*
 Set the number of pictures and position arrangement
 */
function setImgLocation(parent){
var cparent = (parent);//Get the parent nodevar childArray = getChildNodes(cparent);//Get the number of picturesvar imgWidth = childArray[0].offsetWidth;//Get photo widthvar screenWidth = ;//Get the browser widthvar count = (screenWidth/imgWidth);//Number of each row = "width:"+count*imgWidth+"px;margin: 0 auto;";//Set its width and center//Define the array and store the first line of photo heightvar imgHArray = [];
//Loop through the picturefor(var i=0;i<;i++){
// If the image is in the first line, get the heightif(i<count){
imgHArray[i] = childArray[i].offsetHeight;
}else//Otherwise fill the remaining pictures with the minimum height{
var minHeight = (null,imgHArray);//Get the minimum heightvar minIndex = getMinIndex(minHeight,imgHArray);//Get the subscript corresponding to the minimum heightchildArray[i]. = "absolute";//Set the picture box to be filled with absolute layout, otherwise the position cannot be changedchildArray[i]. = minHeight+"px";//Set the height of the image to be filledchildArray[i]. = childArray[minIndex].offsetLeft+"px";//Set the left height of the picture to be filledimgHArray[minIndex] += childArray[i].offsetHeight;//After filling, set the current position height to add two pictures//Start the next cycle}

}

}
/*
 Get the subscript corresponding to the minimum height
 */
function getMinIndex(minHeight,imgHArray){
for(var i in imgHArray){
if(imgHArray[i] == minHeight){
return i;
}
}
}
/*
 Get the number of all pictures
 */
function getChildNodes(parent){
var childArray =[];//Define an array to store image boxvar tempNodes = ("*");//Get all nodes under the parent node//Loop to add the node with class as boxfor(var i = 0;i<;i++){
if(tempNodes[i].className == "box"){
(tempNodes[i]);
}
}
return childArray;//Return all child nodes}

Implement dynamic loading

Dynamic loading means that the scroll bar will never slide at the bottom. To solve the dynamic loading, we need to consider two issues:

1. When will it be loaded?

Sliding distance + browser height > distance from the last image to the top

2. How to load?

By creating a new node, add the created nodes into it

Final code:

/*
 Used to load other functions
 */
 = function() {
var cparent = ("container");//Get the parent nodesetImgLocation(cparent);
//Set loaded picturesvar data = ["image/", "image/", "image/", "image/", "image/", "image/", "image/", "image/", "image/",
"image/", "image/", "image/", "image/", "image/", "image/", "image/"];
//Sliding monitoring = function () {
if (checkLoad(cparent)) {
for (var i = 0; i < ; i++) {
//Create a new nodevar div1 = ("div");
 = "box";
var div2 = ("div");
 = "box_border";
var img = ("img");
 = ".box_border img";
 = data[i];
(img);
(div2);
(div1);
}
setImgLocation(cparent);//Rearrange after creating node}
}
}
/*
 Check if it should be loaded
 */
function checkLoad(cparent){
var childArray = getChildNodes(cparent);//Get the number of picturesvar lastImgHight = childArray[-1].offsetTop;//Get the last image from the top heightvar scrollHeight = ||;//Get sliding distance (browser compatibility is really annoying)var browserHeight = ;//Get browser heightif(lastImgHight < scrollHeight+browserHeight){//Judge whether to loadreturn true;
}else {
return false;
}
}
/*
 Set the number of pictures and position arrangement
 */
function setImgLocation(cparent){
var childArray = getChildNodes(cparent);//Get the number of picturesvar imgWidth = childArray[0].offsetWidth;//Get photo widthvar browserWidth = ;//Get the browser widthvar count = (browserWidth/imgWidth);//Number of each row = "width:"+count*imgWidth+"px;margin: 0 auto;";//Set its width and center//Define the array and store the first line of photo heightvar imgHArray = [];
//Loop through the picturefor(var i=0;i<;i++){
// If the image is in the first line, get the heightif(i<count){
imgHArray[i] = childArray[i].offsetHeight;
}else//Otherwise fill the remaining pictures with the minimum height{
var minHeight = (null,imgHArray);//Get the minimum heightvar minIndex = getMinIndex(minHeight,imgHArray);//Get the subscript corresponding to the minimum heightchildArray[i]. = "absolute";//Set the picture box to be filled with absolute layout, otherwise the position cannot be changedchildArray[i]. = minHeight+"px";//Set the height of the image to be filledchildArray[i]. = childArray[minIndex].offsetLeft+"px";//Set the left height of the picture to be filledimgHArray[minIndex] += childArray[i].offsetHeight;//After filling, set the current position height to add two pictures//Start the next cycle}
}
}
/*
 Get the subscript corresponding to the minimum height
 */
function getMinIndex(minHeight,imgHArray){
for(var i in imgHArray){
if(imgHArray[i] == minHeight){
return i;
}
}
}
/*
 Get the number of all pictures
 */
function getChildNodes(parent){
var childArray =[];//Define an array to store image boxvar tempNodes = ("*");//Get all nodes under the parent node//Loop to add the node with class as boxfor(var i = 0;i<;i++){
if(tempNodes[i].className == "box"){
(tempNodes[i]);
}
}
return childArray;//Return all child nodes}

This is the end of this article about implementing waterfall flow effect (cyclic asymptotic) based on JavaScript. For more related js waterfall flow content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!