Preface:
Waterfall layout, also known as waterfall layout, is a popular way of web page layout. That is, multiple lines of elements of equal width are arranged, the following elements are successively added to the following, the same width and different heights are scaled according to the original proportion of the picture until the width meets our requirements, and then placed in the specified position according to the rules.
What is waterfall flow layout:
First look at the effect:
- The picture is arranged with many lines of equal width elements, and the following elements are successively added to the back of the picture. The same width and different heights are scaled according to the original proportion of the picture until the width meets our requirements, and then placed in the specified position according to the rules.
- For easy understanding, here is the HTML, CSS code
Incomplete HTML code:
<div id="container">
<div class="box">
<div class="box-img">
<img src="./img/1.jpg" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/2.jpg" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/3.jpg" alt="">
</div>
</div>
</div>.<! -- Omit the picture, how many pictures to decide -->
Copy the code
Complete CSS code
* {padding: 0;
margin: 0;
}
#container{
position: relative;
}
.box{
float: left;
padding: 15px;
}
.box-img {
width: 150px;
padding: 5px;
border: 1px solid #ccc ;
box-shadow: 0 0 5px #ccc;
border-radius: 5px;
}
.box-img img{
width: 100%;
height: auto;
}
Copy the code
How to achieve:
Simply put, if you want to achieve a waterfall flow layout, there are several things that need to be done
1. Get pictures
function getChildElemnt() {
const contentArr = []// Define the array ready to install the diagram
const parent = document.getElementById(container)// Get the entire page
const allContent = parent.getElementsByTagName(The '*')// Get the entire tag
console.log(allContent);
for (var i = 0; i < allContent.length; i++) {
if (allContent[i].className == 'box') {
contentArr.push(allContent[i])// Put the class='box' label into the array}}console.log(contentArr);
return contentArr// Return an array
}
Copy the code
2. Set picture broadband
var ccontent = getChildElemnt()
var imgWidth = ccontent[0].offsetWidth// Make all images equal to the width of the first image
Copy the code
3. Calculate the maximum number of images that can be stored in a line on a browser page
var dWidth=document.documentElement.clientWidth// Page width
var num = Math.floor(dWidth/ imgWidth)
// math.floor () rounds down
Copy the code
4. Compare height
- Because in a waterfall layout, when the first row is full, the first image in the second row should be placed below the smallest image in the first row
var BoxHeightArr = []// Define an array to place the height of each image in order
for (var i = 0; i < ccontent.length; i++) {
if (i < num) {
BoxHeightArr[i] = ccontent[i].offsetHeight// Store the height of the image in the array
} else {// When the first line has no more images to store
var minHeight = Math.min.apply(null, BoxHeightArr)// Compare the smallest height of the previous row}}Copy the code
5. Get the position of the minimum height image in the previous row
// Define a getMinHeightLocation function, passing in all the images in the row above BoxHeightArr, and the minimum height of the image in the row above minHeight
function getMinHeightLocation(BoxHeightArr, minHeight) {
for (var i in BoxHeightArr) {
if (BoxHeightArr[i] === minHeight) {// When the height of the picture equals the minimum height, the position of the picture is the position of the minimum height picture
return i
}
}
}
Copy the code
Illustration 6.
for (var i = 0; i < ccontent.length; i++) {
if (i < num) {
BoxHeightArr[i] = ccontent[i].offsetHeight
} else {
var minHeight = Math.min.apply(null, BoxHeightArr)
var minIndex = getMinHeightLocation(BoxHeightArr, minHeight)
ccontent[i].style.position = 'absolute'// The image to be inserted is absolutely positioned, i.e. the position of the element is specified by the "left", "top", "right" and "bottom" attributes
ccontent[i].style.top = minHeight + 'px'// Make the distance from the top of the inserted image equal to the height of the image below it
ccontent[i].style.left = ccontent[minIndex].offsetLeft + 'px'// Make the distance from the image to the left of the image to be inserted exactly equal to the distance from the image below
BoxHeightArr[minIndex] = BoxHeightArr[minIndex] + ccontent[i].offsetHeight// After inserting the image, set the height of this position to the sum of the height of the two images}}Copy the code
The complete code is as follows:
Optimize code to improve performance
window.onload = function() {
imgLocation('container'.'box')// Constructor imgLocation
}
// Use window.onload = function() {} instead of waiting for the body page to call
// Get the current number of images to display
function imgLocation(parent, content) {// make parent='container', content='box'
// Remove all contents under parent
var cparent = document.getElementById(parent)
var ccontent = getChildElemnt(cparent, content)
var imgWidth = ccontent[0].offsetWidth
var num = Math.floor(document.documentElement.clientWidth / imgWidth)
cparent.style.cssText = `width: ${imgWidth * num} px`
var BoxHeightArr = []
for (var i = 0; i < ccontent.length; i++) {
if (i < num) {
BoxHeightArr[i] = ccontent[i].offsetHeight
} else {
var minHeight = Math.min.apply(null, BoxHeightArr)
var minIndex = getMinHeightLocation(BoxHeightArr, minHeight)
ccontent[i].style.position = 'absolute'
ccontent[i].style.top = minHeight + 'px'
ccontent[i].style.left = ccontent[minIndex].offsetLeft + 'px'
BoxHeightArr[minIndex] = BoxHeightArr[minIndex] + ccontent[i].offsetHeight
}
}
// console.log(BoxHeightArr);
}
function getChildElemnt(parent, content) {parent='container'And the content ='box'
const contentArr = []
const allContent = parent.getElementsByTagName(The '*')
console.log(allContent);
for (var i = 0; i < allContent.length; i++) {
if (allContent[i].className == content) {
contentArr.push(allContent[i])
}
}
console.log(contentArr);
return contentArr
}
function getMinHeightLocation(BoxHeightArr, minHeight) {
for (var i in BoxHeightArr) {
if (BoxHeightArr[i] === minHeight) {
return i
}
}
}
Copy the code
I am a junior student in school, and I am also summarizing while learning. If there is something wrong with my writing, please comment 🙏🙏🙏