制作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);//填充數組為0for (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坐標,以及圖片的異步加載
總結
以上是生活随笔為你收集整理的制作js原生瀑布流插件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 高德地图接口调用
- 下一篇: GitHub Universe 2019