什么是瀑布流和懶加載
瀑布流是目前比較流行的一種網(wǎng)站頁面布局她君,會在網(wǎng)頁上呈現(xiàn)參差不齊的多欄布局墨技,頁面向下滾動,網(wǎng)頁就會不斷加載數(shù)據(jù)塊并附加至當(dāng)前頁面尾部辐赞。
它的好處就是按需加載:
根據(jù)我們每行圖片的最小高度來動態(tài)的加載圖片
1.首屏加載的是減少向http請求次數(shù)
2.減少瀏覽器以及服務(wù)器的內(nèi)存負(fù)荷
效果圖是這樣滴
首先看一下布局:
// html部分 img標(biāo)簽部分發(fā)布的時候就變成了![]了,硝训,不知道怎么改
<div id="container">
<div class="box">
<div class="box-img">
![](images/0.jpg)
</div>
</div>
<div class="box">
<div class="box-img">
![](images/1.jpg)
</div>
</div>
<div class="box">
<div class="box-img">
![](images/2.jpg)
</div>
</div>
<div class="box">
<div class="box-img">
![](images/3.jpg)
</div>
</div>
<div class="box">
<div class="box-img">
![](images/4.jpg)
</div>
</div>
<div class="box">
<div class="box-img">
![](images/5.jpg)
</div>
</div>
<div class="box">
<div class="box-img">
![](images/6.jpg)
</div>
</div>
<div class="box">
<div class="box-img">
![](images/7.jpg)
</div>
</div>
<div class="box">
<div class="box-img">
![](images/8.jpg)
</div>
</div>
<div class="box">
<div class="box-img">
![](images/9.jpg)
</div>
</div>
<div class="box">
<div class="box-img">
![](images/10.jpg)
</div>
</div>
<div class="box">
<div class="box-img">
![](images/11.jpg)
</div>
</div>
</div>
// CSS部分
*{
margin: 0;
padding: 0;
}
#container{
position: relative;
}
.box{
float: left;
padding: 5px;
}
.box-img{
padding: 5px;
border: 1px solid #ccc;
box-shadow: 0 0 5px #ccc;
border-radius: 5px;
}
.box-img img{
width: 230px;
height: auto;
}
JS部分的邏輯
首先我們得秉承著多人協(xié)作的思想來寫占拍,因為代碼不一定只是給一個人看到,所以為了避免全局污染捎迫,要用函數(shù)模塊化封裝的的思想。如果直接寫在全局表牢,一個項目可能有多個模塊函數(shù)窄绒,命名變量名的時候并不知道其他人的命名,可能會導(dǎo)致bug崔兴。所以全局部分只寫怎么來用這個封裝好了的函數(shù)彰导。
window.onload = function () {
imgLocation('container', 'box');
// 模仿數(shù)據(jù)
var imgData = {"data": [{"src":"24.jpg"},{"src":"25.jpg"},{"src":"26.jpg"},{"src":"27.jpg"},{"src":"28.jpg"}]};
window.onscroll = function () {
if (checkFlag()) {
var cparent = document.getElementById("container");
for (var i =0; i<imgData.data.length; i++) {
var ccontent = document.createElement('div');
ccontent.className = 'box';
cparent.appendChild(ccontent);
var boxImg = document.createElement('div');
boxImg.className = 'box-img';
ccontent.appendChild(boxImg);
var img = document.createElement("img");
img.style.cssText = 'opacity: 0; transform:scale(0)';
img.src = "images/" + imgData.data[i].src + "";
boxImg.appendChild(img);
(function(img){ // 自執(zhí)行程序閉包
setTimeout(function(){
img.style.cssText="opacity:1;transform:scale(1)";
},1000); // 這里的時間自定蛔翅,我是為了測試才寫的1000
})(img);
}
imgLocation('container', 'box');
}
}
};
首先我們得定位圖片的位置
function imgLocation(parent, content) {
// 將parent下面的所有content全部取出
var cparent = document.getElementById(parent);
var ccontent = getChildElement(cparent, content);
// 完善圖片布局
var imgWidth = ccontent[0].offsetWidth; // 圖片的寬度
var num = Math.floor(document.documentElement.clientWidth / imgWidth); // 橫排的顯示個數(shù)
cparent.style.cssText = "width:" + imgWidth * num + "px;margin: 0 auto"; // 給父級添加寬度
// 計算圖片的高度
var boxHeightArr = [];
for (var i=0; i<ccontent.length; i++) {
if(i < num) {
boxHeightArr[i] = ccontent[i].offsetHeight;
console.log(boxHeightArr);
} else {
var minHeight = getMin(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; // 更新最小高度
}
}
}
這里面有三個函數(shù),一個是得到圖片最小高度的函數(shù)getMin(arr)
位谋,為什么要得到最小高度山析?因為我們計算第一排最小高度的圖片之后,第二排的圖片排序是這樣的掏父,第一張排在第一排的最小高度圖片下笋轨,第二張排在第一排倒數(shù)第二高度圖片下,依次排完第二排赊淑,后面的圖片排序都是按照這樣來排爵政。
function getMin(arr) { // 得到圖片的最小高度
for(var i=0, ret=arr[0]; i<arr.length; i++) {
ret = Math.min(ret, arr[i]); // 依次將最小值賦值給ret,ret始終最小
}
return ret;
}
還有一個函數(shù)是得到最小高度圖片索引getMinheightLocation
:
function getMinheightLocation(boxHeightArr, minHeight) { // 得到圖片最小高度的序列號
for (var i in boxHeightArr) {
if ( boxHeightArr[i] === minHeight) {
return i;
}
}
}
要得到索引位置陶缺,才能將圖片排在這個索引位置下钾挟。
另外一個是得到子集空間的函數(shù),一開始就強(qiáng)調(diào)要用模塊化的思想來做饱岸,我們要做的是函數(shù)之外掺出,全局部分才用html
里的id值,函數(shù)只通過傳參來得到里面的東西苫费。
function getChildElement(cparent, content) { // 得到子集空間
var contentArr = [];
var allcontent = cparent.getElementsByTagName('*'); // 獲取到所有的元素
for (var i=0; i<allcontent.length; i++ ) {
if (allcontent[i].className === content) {
contentArr.push(allcontent[i]);
}
}
return contentArr;
}
關(guān)于懶加載
懶加載的思想是 頁面的高度 + 滾動的高度 > 最后一張圖片距離瀏覽器頂部的高度汤锨,然后就開始加載圖片。
function checkFlag() {
var cparent = document.getElementById('container');
var ccontent = getChildElement(cparent, "box");
// 數(shù)組最后一個元素的高度距離頂部的距離
var lastContentHeight = ccontent[ccontent.length-1].offsetTop;
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
var pageHeight = document.documentElement.clientHeight || document.body.scrollHeight;
if(lastContentHeight < scrollTop + pageHeight){
return true;
}
}