JavaScript實現瀑布流效果

在極客學院下載的js基礎視頻中學習到了用js實現瀑布流效果,然后自己總結了兩個關鍵的點,一個是瀑布流效果的實現,另一個是下拉動態加載圖片

首先是HTML代碼,如下:

<div id="container">
      <div class="box">
            <div class="imgBox">
               ![](images/1.jpg)
            </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屬性的個數,創建對應的類名為imgBoxBoxdiv標簽,然后將標簽插入到container容器中。最后只得注意的是,加載完了7張照片之后,要對新加入的圖片繼續調用imgLocation函數進行定位,否則不會有瀑布流的效果

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 只放了js部分,剛希望多多指出錯誤 window.onload=function(){ //實現瀑布流布局 wat...
    grin_sun閱讀 473評論 3 1
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,296評論 25 708
  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,800評論 1 92
  • html結構 (Emmet) (div.box>div.pic>img[src="images/$.jpg"])*...
    LaBaby_閱讀 658評論 0 0
  • 中庸 我的理解 領導應遵循以下九條管理法則: 1修養自身,不做不合禮的事,這是做領導永遠的前提基礎; 2尊重賢能的...
    山緣有約閱讀 207評論 0 0