Waterfall, also known as waterfall-style layout, is a popular website page layout. It visually presents a multi-column layout with irregular heights. As the page scroll bar scrolls down, this layout continuously loads data blocks and appends them to the current end. The main feature of the waterfall layout is its organized and fixed-width but variable-height design, which distinguishes it from the traditional matrix-style image layout pattern.
The main idea is to record the height of each column. The parent container is relatively positioned, and the members are absolutely positioned. The top
and left
properties are used to control the position. When adding a new member, find the column with the lowest height and place the member below it to achieve the waterfall layout. If dynamic addition of members is not needed and only one-time loading for display is required, you can consider using the flex
layout to set the container as flex-direction: column;
and flex-wrap: wrap;
, and give the container a suitable height to achieve the layout. You can also use the column-*
multi-column layout introduced by CSS3 to achieve this. These two methods are pure CSS implementations of the waterfall layout. However, because both methods arrange members vertically, they are not suitable for layouts that require dynamic insertion of members. When dynamic insertion of members is needed, JavaScript is still required for implementation.
<!DOCTYPE html>
<html>
<head>
<title>JavaScript Waterfall Layout</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1" />
<style type="text/css">
#container{
position: relative; /* Parent container relative */
}
.item{
position: absolute; /* Members set as absolute */
display: flex; /* Mainly for centering text */
justify-content: center; /* Horizontal centering */
align-items: center; /* Vertical centering */
color: #fff; /* Font color white */
}
</style>
</head>
<body>
<div id="container"></div>
</body>
<script type="text/javascript">
var column = 3; // Create a three-column layout
var counter = 0; // Counter for displaying the current block
var columnHeight = Array(column).fill(0); // Record the height of each column
var container = document.getElementById("container"); // Parent container object
var colorList = ["#EAA78C", "#F9CD82", "#9ADEAD", "#9CB6E9", "#E49D9B", "#97D7D7", "#ABA0CA", "#9F8BEC","#ACA4D5", "#6495ED", "#7BCDA5", "#76B4EF","#E1C38F","#F6C46A","#B19ED1","#F09B98","#87CECB","#D1A495","#89D196","#FE9E9F", "#93BAFF", "#D999F9", "#81C784", "#FFCA62", "#FFA477"]; // Color list
function random(min=0, max=1) { // Generate random numbers
return min + ~~((max-min)*Math.random()) // min <= random < max
}
function findMinColumn(arr) { // Find the column with the minimum height
var min = arr[0];
var index = 0;
arr.forEach((v, i) => {
if (v < min) {
min = v;
index = i;
}
})
return [index, min];
}
function appendImg() {
var gap = 3; // Set the gap to 3px
for (let i = 0; i < 12; ++i) { // Load 12 members each time
var unit = {
height: random(100, 500), // Randomize an undefined height
width: 300, // Set width
color: colorList[random(0, colorList.length)] // Randomize color
}
var [minIndex, min] = findMinColumn(columnHeight); // Get the column with the minimum height and its index
var d = document.createElement("div"); // Create a node
d.className = "item"; // Set class
d.style.background = unit.color; // Set background color
d.style.height = `${unit.height}px`; // Set height
d.style.width = `${unit.width}px`; // Set width
d.style.top = `${min + gap}px`; // Set top offset
d.style.left = `${(300 + gap) * minIndex}px`; // Set left offset
d.innerText = `${++counter}#${unit.height}X${unit.width}`; // Set text
columnHeight[minIndex] += (unit.height + gap); // Update the height of the selected column
container.appendChild(d); // Add node
}
}
function init() {
appendImg(); // Initial load
var endLoad = columnHeight.some(v => v > window.innerHeight); // Check if any column height is greater than the screen height
if (!endLoad) init(); // If not, recursively call to continue loading
}
(function () {
init(); // Automatically load when the page opens
})();
window.onscroll = function (){ // Browser scroll to bottom event
var marginBottom = 0;
if (document.documentElement.scrollTop){
var scrollHeight = document.documentElement.scrollHeight;
var scrollTop = document.documentElement.scrollTop + document.body.scrollTop;
var clientHeight = document.documentElement.clientHeight;
marginBottom= scrollHeight - scrollTop - clientHeight;
} else {
var scrollHeight = document.body.scrollHeight;
var scrollTop = document.body.scrollTop;
var clientHeight = document.body.clientHeight;
marginBottom= scrollHeight - scrollTop - clientHeight;
}
if(marginBottom<=0) appendImg();
}
</script>
</html>
https://github.com/WindrunnerMax/EveryDay
https://www.cnblogs.com/imgss/p/11072266.html
https://blog.csdn.net/weixin_44135121/article/details/98629830