1. 程式人生 > >原生JS實現瀑布流布局

原生JS實現瀑布流布局

jpg 相對布局 復制 圖像 == borde 一行 原生 per

一.瀑布流之準備工作

   首先聲明下, 為了方便演示和聯系, 我使用的是本地圖片, 如果大家有需要的話可以嘗試著寫下網絡的, 不過本地和遠端的大致是相同的. 那麽我就來簡單介紹下本地的瀑布流效果吧, 我們要先準備好八九張圖片, 當然啦, 我們實現的是瀑布流效果, 所以最好是高度不相同的, 這樣才可以看出來效果, 對吧, 嘿嘿.

二.代碼的準備工作

   我們打開開發工具, 先建個html工程, 在內部寫下如下代碼, 因為是準備工作, 所以剛開始寫的都是一些基礎性的東西, 就不一一解釋了, 直接上代碼:

技術分享圖片技術分享圖片?

<body>
<div id="container">
    <div class="box">
        <div class="boximg">
            <img src="img/1.jpeg">
        </div>
    </div>
    <div class="box">
        <div class="boximg">
            <img src="img/2.jpg">
        </div>
    </div>
    <div class="box">
        <div class="boximg">
            <img src="img/3.jpg">
        </div>
    </div>
    <div class="box">
        <div class="boximg">
            <img src="img/4.jpg">
        </div>
    </div>
    <div class="box">
        <div class="boximg">
            <img src="img/5.jpg">
        </div>
    </div>
    <div class="box">
        <div class="boximg">
            <img src="img/6.jpg">
        </div>
    </div>
    <div class="box">
        <div class="boximg">
            <img src="img/7.gif">
        </div>
    </div>
    <div class="box">
        <div class="boximg">
            <img src="img/8.jpg">
        </div>
    </div>
    <div class="box">
        <div class="boximg">
            <img src="img/9.jpg">
        </div>
    </div>
    <div class="box">
        <div class="boximg">
            <img src="img/9.jpg">
        </div>
    </div>
    <div class="box">
        <div class="boximg">
            <img src="img/9.jpg">
        </div>
    </div>
    <div class="box">
        <div class="boximg">
            <img src="img/9.jpg">
        </div>
    </div>

</div>

</body>
技術分享圖片

技術分享圖片技術分享圖片?

   很明顯這段代碼中也就是幾個div標簽和幾個img標簽, 所以是很簡單的, 就不多說了, 下面我們來布置css樣式.

三.css樣式布置

   說句比較實在的話, 對於瀑布流而言, 因為我只是簡單的模擬下, 所以css樣式的定制, 我並沒有特別復雜的定制, 只是簡單的把邊框和容器(div)大小給定制了下, 還有一些顏色, 話不多說, 直接上代碼吧

技術分享圖片技術分享圖片?

/*使用通配符將內外邊距都設置為零, 這樣看著好看*/
*{
    margin: 0px;
    padding: 0px;
}
/*將主容器的布局方式設置為相對布局*/
#contianer{
    position: relative;
}

.box{
    padding: 5px;
    float: left;
}
/*將承載圖片的容器定制顏色及邊框大小和圓角*/
.boximg{
    padding: 5px;
    box-shadow: 0 0 5px #ccc;
    border: 1px solid #cccccc;
    border-radius: 5px;
}
/*定制圖片尺寸*/
.boximg img{
    width: 250px;
    height: auto;
}
技術分享圖片

技術分享圖片技術分享圖片?

  代碼中註釋已經解釋的很清楚了, 就不再過多的贅述了.

四.重點也是瀑布流的難點(JS的實現)

   大家對於瀑布流都不陌生吧, 它主要是頂寬的, 然後根據高度來進行布局, 也就是說在第一行鋪滿後, 準備排布第二行的時候, 將第二行的第一種圖片放在第一行圖片高度最小處, 之後依次類推, 先簡單的上些代碼, 然後一一作解釋了, 正所謂有圖有真相, 哈哈!

技術分享圖片技術分享圖片?

   這就是在未編寫js代碼時的效果圖, 那麽按道理來說下面的圖片應該放在第一行第二張圖片的位置下面, 應該充分利用空白資源, 那麽這要如何來實現呢, 接下來我就附上代碼來告訴大家了:

技術分享圖片技術分享圖片?

window.onload = function(){
    waterFlow("container", "box");
   
}
function waterFlow(parent, chirld){
    var wparent = document.getElementById(parent);//獲取父級div, 最外級容器
    var allArr = getAllChirld(wparent,chirld);//獲取到所有的class為box的容器div
    var wscreenWidth = document.documentElement.clientWidth;//獲取屏幕寬度
    var wchirldWidth = wparent.getElementsByTagName("*");//獲取所有的標簽
    var num = Math.floor(wscreenWidth/wchirldWidth[0].offsetWidth);//這是一個Math算法, 目的是將小數轉變為整數,
    // 從而可以知道每行最多容納幾張圖片
    wparent.style.cssText = ‘width:‘+wchirldWidth[0].offsetWidth*num+‘px;margin:0 auto‘;//固定每行擺放個數 和上下左右邊距
    //獲得每行的最小高度
    getMinHeightOfCols(allArr, num);
}
function getAllChirld(parent,classname){
    //獲取所有的標簽
    var wchirld = parent.getElementsByTagName("*");
    //創建數組
    var chirldArr = [];
    //遍歷wchirld, 將其中className等於classname(傳進來的參數)相同的標簽放入數組chirldArr中
    for(var i = 0; i<wchirld.length; i++){
        if(wchirld[i].className==classname){
            //因為是位push所以沒放進去一個, 都是在數組的最後一個
            chirldArr.push(wchirld[i]);
        }
    }
    //返回該數組
    return chirldArr;
}
function getMinHeightOfCols(chirdArr, num){
    //創建數組, 用來盛放每一行的高度
    var onlyOneColsArr = [];
    for(var i = 0; i<chirdArr.length; i++){

        if(i<num){
            //num為傳進來的參數, 即為每行放圖片的張數, 此步驟的目的是為了將第一行每張圖片的高度遍歷出來存放如新數組
            onlyOneColsArr[i]=chirdArr[i].offsetHeight;
        } else {
            //當大於每行存放的圖片個數時進入該方法, Math.min.apply這個方法是為了得到數組中的最小值
            var minHeightOfCols = Math.min.apply(null, onlyOneColsArr);
            //此方法的目的是為了得到最小高度圖片的下表, 也就是在每行的第幾張, 具體方法見下面
            var minHeightOfindex = getminIndex(onlyOneColsArr, minHeightOfCols);
            //定義布局方式為絕對布局
            chirdArr[i].style.position = "absolute";
            //得到下一行圖片應放的高度
            chirdArr[i].style.top = minHeightOfCols + "px";
            //得到下一行圖片應放於那個位置
            chirdArr[i].style.left = chirdArr[minHeightOfindex].offsetLeft + "px";
            //將兩張圖片高度相加得到一個新的高度用來進行下一次的計算
            onlyOneColsArr[minHeightOfindex] += chirdArr[i].offsetHeight;
        }
    }

}
//此方法是為了進行最小高度下標的確定
function getminIndex(onlyOneColsArr, min){
    //遍歷傳進來的高度數組
        for(var i in onlyOneColsArr){
            //如果高度等於最小高度, 返回i即為該圖片下標
            if(onlyOneColsArr[i] == min){
                return i;
            }
        }
}
技術分享圖片

原生JS實現瀑布流布局