瀑布流簡介與JS簡易實作
瀑布流
瀑布流,又稱瀑布流式布局,是比較流行的一種網站頁面布局,視覺表現為參差不齊的多欄布局,隨著頁面滾動條向下滾動,這種布局還會不斷加載資料塊并附加至當前尾部,最早采用此布局的網站是Pinterest,逐漸在國內流行開來,國內大多數清新站基本為這類風格, 
(本文主要介紹JS實作部分,html部分甚為簡略,后會將代碼一同貼在文章結尾處)
特點
1.瀑布流對用戶來說有著很強的吸引力,瀑布流會在它的頁面底部給用戶不斷地加載新的暗示資訊,通過給出不完整的視覺圖片去吸引你的好奇心,讓你停不下來地想要向下不斷地探索,
2、瀑布流的資訊較為集中,可以在最小的操作成本下能夠獲得最多的內容體驗,因此瀑布流能更好的適應移動端,由于移動設備螢屏比電腦小,一個螢屏顯示的內容不會非常多,因此可能要經常翻頁,而在建網站時使用瀑布流布局,用戶則只需要進行滾動就能夠不斷瀏覽內容,
3、另外瀑布流的主要特質就是:定寬而不定高,這樣的頁面設計區別于傳統的矩陣式圖片布局模式,巧妙的利用視覺層級,視線的任意流動來緩解視覺的疲勞,
實作原理
瀑布流有兩大特征
1.內容框寬度固定,高度不固定,
2.內容框從左到右排列,一行排滿后,其余內容框就會按順序排在短的一列后,
(可以用最小二叉樹來類比瀑布流的形成演算法)

首先我們先通過計算一行能夠容納幾列元素(因為我們需要在不同的設備上瀏覽)

然后在通過計算比較找出這一列元素中高度之和最小一列
(假設就是我們框起來的這一列)

然后將下一行的第一個元素添加至高度之和最小的這一列的下面

然后繼續計算所有列中高度之和最小的那一列,然后繼續將新元素添加至高度之和最小的那一列后面,直至所有元素添加完畢,

實作步驟及演算法
1.將圖片匯入,后將其統一定位為 position:relative
#container{
position: relative;
}
2.建立一個JS檔案并在html檔案中引入
<script src="./index.js"></script>
3.全域監聽每一張圖片加載時的狀況,以備后續圖片的安放
window.onload = function () {
imgLocation('container', 'box')
}
4.拿到頁面上所有要擺放的圖片的數量
function imgLocation(parent, content) {
var cparent = document.getElementById(parent)
var ccontent = getChildElemnt(cparent, content)
}
function getChildElemnt(parent, content) {
const contentArr = []
const allContent = parent.getElementsByTagName('*')
//取到‘parent’中的所有的子容器
for (var i = 0; i < allContent.length; i++) {
if (allContent[i].className == content) {
contentArr.push(allContent[i])
}
}
// 取到想要的子容器的數量
return contentArr
}
//這里也可以使用dom的querySelectorAll()方法
5.找到圖片的寬度和需要圖片進行插入的位置
var imgWidth = ccontent[0].offsetWidth
//拿到圖片的寬度
var num = Math.floor(document.documentElement.clientWidth / imgWidth)
//得到一橫行可以放置圖片的數量
cparent.style.cssText = `width: ${imgWidth * num} px`
6.在確切位置上放置需要被放置的圖片,并進行回圈,將該頁面上的所有圖片按需要的位置加入
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
}
}
function getMinHeightLocation(BoxHeightArr, minHeight) {
for (var i in BoxHeightArr) {
if (BoxHeightArr[i] === minHeight) {
return i
}
}
}
代碼分享
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js 瀑布流</title>
<style>
*{
margin: 0;
padding: 0;
}
#container{
position: relative;
}
.box{
float: left;
padding: 5px;
}
.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;
}
</style>
</head>
<body>
<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 class="box">
<div class="box-img">
<img src="./img/4.jpg" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/5.jpg" alt="">
</div>
</div>
</div>
<script src="./index.js"></script>
</body>
</html>
JS
window.onload = function () {
imgLocation('container', 'box')
}
// 獲取到當前有多少張圖片要擺放
function imgLocation(parent, content) {
// 將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) {
const contentArr = []
const allContent = parent.getElementsByTagName('*')
// 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
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/277346.html
標籤:其他
上一篇:for回圈中的函式使用axios請求資料,拿不到資料?
下一篇:JS 基礎面試題
