在極客學院下載的js基礎視頻中學習到了用js實現瀑布流效果,然后自己總結了兩個關鍵的點,一個是瀑布流效果的實現,另一個是下拉動態加載圖片。
首先是HTML代碼,如下:
<div id="container">
<div class="box">
<div class="imgBox">

</div>
</div>
......
</div>
- 一個父容器
contanier
中多個放圖片的盒子,至于為什么要用兩個div
來包含住img標簽,是為了后面設置position
屬性而用的。
其次是CSS代碼,如下:
*{margin:0px;padding:0px;}
#container{
position:relative;
}
.box{
float:left;
padding:5px;
}
.imgBox{
padding:5px;
border:1px solid #CCCCCC;
box-shadow: 0 0 5px #CCC;
border-radius:5px;
}
.imgBox img{
width:200px;
height:auto;
}
- 這里為了好看,給圖片設置了邊框,內邊距還有陰影的效果,HTML和CSS代碼都比較簡單,重點還是放在JS的實現上。
由于JS的代碼比較多,我就一個個函數,按照順序來分析,
function imgLocation(parent,content){
//將parent下所有content取出
var cparent=document.getElementById(parent);
var ccontent = getChildElement(cparent,content);
var imgWidth=ccontent[0].offsetWidth;//獲得圖片的寬度
var cols=Math.floor(document.documentElement.clientWidth / imgWidth);//獲得瀏覽器一行可以容納的圖片數
cparent.style.cssText="width:"+imgWidth*cols+"px;margin:0 auto";//通過style.cssText來改變元素的樣式
//確定位置
var BoxHeightArr=[];
//判斷一排中的最小位置
for(var i=0;i<ccontent.length;i++){
if(i<cols){
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;//改變原來最小高度圖片的高度
}
}
}
第一個函數叫做imgLocation
,顧名思義是用來給圖片定位的,該函數會傳入兩個參數,一個是父元素,這里就是我們的container
,另一個參數是內容,這里就是我們的imgBox
。
- 首先我們要知道容器中有多少張圖片,然后確定瀏覽器中,一行放多少張圖片,其中用到了
getChildElement
函數來獲得容器中圖片的個數,具體代碼如下:
//獲得圖片的個數
function getChildElement(parent,content){
var contenArr=[];//定義一個數組contenArr
var allContent = parent.getElementsByTagName("*");//獲得父元素下的所有元素
for(var i=0;i<allContent.length;i++){
if(allContent[i].className==content){
contenArr.push(allContent[i]);
}
}
return contenArr;
}
- 確定好了一行放多少張圖片之后,就要確定一排中高度最小的那張圖片,以便確定超出列數之后的第一張圖片的位置,這里面用了一個
for
循環,遍歷容器中的圖片,如果沒有超出一行放圖片的個數,就只存入一行的高度到數組BoxHeightArr
中,當超出的時候,首先用Math.min.apply(null,BoxHeightArr);
求出一行中圖片的最小高度,然后通過getminheightLocation
函數獲得最小高度圖片的位置索引,具體代碼如下:
/得到高度最小圖片的位置
function getminheightLocation(BoxHeightArr,minHeight){
for(var i=0;i<BoxHeightArr.length;i++){
if(BoxHeightArr[i]==minHeight){
return i;
}
}
}
- 最后就將超出列數之后的第一張圖片放到高度最小圖片的下面,具體方法如下
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
這樣就完成了瀑布流的效果,接下來就要實現下拉動態加載圖片,首先需要綁定一個監聽滾動條的事件,具體代碼如下:
//監聽滾動條
window.onscroll=function(){
if(checkFlag("container","box")){
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="imgBox";
ccontent.appendChild(boximg);
var img=document.createElement("img");
img.src="images/"+imgData.data[i].src;
boximg.appendChild(img);
}
imgLocation("container","box");//對新加入的圖片繼續調用imgLocation函數
}
}
首先通過checkFlag("container","box")
判斷,是否到達最后一張圖片,具體代碼如下:
window.onload=function(){
imgLocation("container","box");
}
function checkFlag(parent,content){
var cparent=document.getElementById(parent);
var ccontent=getChildElement(cparent,content);
var lastContentHeight=ccontent[ccontent.length-1].offsetTop;//得到最后一張圖片的頂部高度
var scrolltop=document.documentElement.scrollTop||document.body.scrollTop;//得到滾動的高度
var pageHeight=document.documentElement.clientHeight||document.body.clientHeight;//得到屏幕的高度
if(scrolltop+pageHeight>lastContentHeight){
return true;
}
}
-
lastContentHeight
的值是最后一張圖片距離頂部的高度,scrolltop
的值是滾動的高度,就是當前顯示頁面之前隱藏的部分,pageHeight
就是當前可見頁面的高度,如果scrolltop
加上pageHeight
大于lastContentHeight
,就返回true
,這個很好理解。
判斷完了,到達最后一張圖片之后,就要動態添加圖片,這里用到了JSON數據格式,具體代碼如下:
var imgData={"data":[{"src":"2.jpg"},{"src":"3.jpg"},{"src":"4.jpg"},{"src":"5.jpg"},{"src":"6.jpg"},{"src":"7.jpg"}]};
根據imgData對象中的data屬性的個數,創建對應的類名為imgBox
和Box
的div
標簽,然后將標簽插入到container
容器中。最后只得注意的是,加載完了7張照片之后,要對新加入的圖片繼續調用imgLocation
函數進行定位,否則不會有瀑布流的效果