js原生瀑佈流插件制作

本文實例為大傢分享瞭js原生瀑佈流插件制作的具體代碼,供大傢參考,具體內容如下

先看效果

和普通的瀑佈流是一樣的,在調用時制需要傳入容器,圖片以及圖片寬度即可直接生成瀑佈流

話不多說,看代碼,後面說一下思路

1.html以及調用,其中HTML隻需要一行

<body>
    <div class="main"></div>
 
    <script src="index.js"></script>
    <script>
        // 第一個參數,瀑佈流容器
        var dom = document.getElementsByClassName("main")[0];
        // 第二個參數,圖片鏈接,寫入一個數組
        var imgArr = ["img/0.jpg","img/45.jpg","img/225.jpg","img/3.png","img/7729.png","img/a.jpg","img/ama.jpg","img/c.png","img/0.jpg","img/3.png","img/45.jpg","img/225.jpg","img/7729.png","img/a.jpg","img/ama.jpg","img/c.png",];
        // 調用插件,傳入參數,第三個是圖片寬度
        waterFallFlow(dom,imgArr,220);
    </script>
</body>

2.HTML對應的css

.main是傳入的容器,其中position: relative;是必須要的

然後.main img{transition: all 0.5s;}是動畫代碼,給容器內所有圖片添加

.main{
    border: 1px solid #ccc;
    width: 90%;
    margin: 0 auto;
    position: relative;
}
.main img{
    transition: all 0.5s;
}

然後是js

/**
 * @param {*} dom 代表瀑佈流容器
 * @param {*} imgArr 圖片數組
 * @param {*} wid 圖片寬度
 */
function waterFallFlow(dom, imgArr, wid) {
    var gap;//間隙
    var colNumber;//列數
    imgDom();
    setImgPos();
    //窗口發生改變的時候
    window.onresize = function(){
        setImgPos();
    }
    /**var timer = null;
     * 上面這麼寫,絲滑,但是過於影響性能,拖動窗口時
     * 非常非常頻繁的調用函數對圖片進行重新拍排佈
     * 
     * 可以這樣,防抖
     * 
     * window.onresize = function(){
     * if(timer){
     *  clearIntval(timer);
     * }
     *  timer = setTimeout(function(){
     *  setImgPos();
     * },300);
     * }
     * 
     */
    // 生成DOM元素
    function imgDom() {
        for (let i = 0; i < imgArr.length; i++) {
            const url = imgArr[i];
            let img = document.createElement("img");
            img.src = url;
            img.style.width = wid + "px";
            img.style.position = "absolute";
            // 所有圖片使用絕對定位
            img.style.left = "";
            img.style.top = "";
            img.onload = function(){
                setImgPos();//圖片的異步加載
            }
            dom.appendChild(img);
        }
    }
    // 設置每張圖片的坐標
    function setImgPos() {
        cal();
        var colY = new Array(colNumber);//存放每一列下一個圖片的Y坐標
        colY.fill(0);//填充數組為0
        for (let i = 0; i < dom.children.length; i++) {
            var imgM = dom.children[i];
            var y = Math.min(...colY);//求最小值
            var index = colY.indexOf(y);//第幾列
            var x = (index + 1) * gap + index * wid;
            imgM.style.left = x + "px";
            imgM.style.top = y + "px";
            //更新數組
            colY[index] += parseInt(imgM.height)+gap;
        }
        //找到數組中最大的數字,來解決父級div塌陷問題
        var h = Math.max(...colY);
        console.log(h);
        dom.style.height = h + "px";
    }
    // 計算相關數據
    function cal() {
        var containerWidth = parseInt(dom.clientWidth);
        colNumber = Math.floor(containerWidth / wid);//列數
        var space = containerWidth - colNumber * wid;
        gap = space / (colNumber + 1);//計算間隙
 
    }
}

基本上我都寫瞭註釋,都可以看懂

來看思路

1.接受傳入的參數,容器,圖片數組,圖片寬度

2.創建圖片元素,添加到對應容器中

3.給每個圖片設置寬度,高度自適應,求列數,間距

4.給圖片利用絕對定位來排佈圖片,計算對應的left和top值,也就是對應的x,y坐標

前三步應該沒有問題,來看第四步

想法是這樣的

主要思路就是尋找最短的一列來排佈下一張圖片,現在最短出現在第二列

這個時候圖片添加到瞭之前最短的第二列,現在繼續尋找最短的一列,繼續添加圖片

這樣此類推完成瀑佈流的排佈,來看看具體過程

首先計算出一共有幾列圖片,創建一個長度為列數的數組,全部填充為0,用來後面存放y坐標

遍歷容器內子元素,在循環中求出當前數組中最小值以及最小值所在位置(列數)就是y坐標

這個時候就可以求x坐標瞭

x = (列數+1)* 間距 + 當前列 * 寬度(傳入的實參)

這樣就有瞭位置

要註意每次需要更新一下數組,就是修改添加圖片位置的y坐標,以及圖片的異步加載

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: