圖片瀑布流實現
阿新 • • 發佈:2018-11-27
實現思路:圖片寬度一定,高度不同,下一行的第一張圖片放在高度最小的圖片的下方,以此類推。
實現程式碼:
html程式碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>js實現瀑布流效果</title> <link href="css/index.css" rel="stylesheet"> <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script> </head> <body> <div id="container"> <div class="box"> <div class="pic"> <img src="images/01.jpg"> </div> </div> <div class="box"> <div class="pic"> <img src="images/02.jpg"> </div> </div> <div class="box"> <div class="pic"> <img src="images/03.jpg"> </div> </div> <div class="box"> <div class="pic"> <img src="images/04.jpg"> </div></div> <div class="box"> <div class="pic"> <img src="images/05.jpg"> </div> </div> <div class="box"> <div class="pic"> <img src="images/06.jpg"> </div> </div> <div class="box"> <div class="pic"> <img src="images/01.jpg"> </div> </div> <div class="box"> <div class="pic"> <img src="images/02.jpg"> </div> </div> <div class="box"> <div class="pic"> <img src="images/03.jpg"> </div> </div> <div class="box"> <div class="pic"> <img src="images/04.jpg"> </div> </div> <div class="box"> <div class="pic"> <img src="images/05.jpg"> </div> </div> <div class="box"> <div class="pic"> <img src="images/06.jpg"> </div> </div> </div> <script src="js/index.js"></script> </body> </html>
JavaScript程式碼:
var parent = document.getElementById('container'); function WaterFall() { imgLocation('box'); const data = [{'img':'01.jpg'},{'img':'02.jpg'},{'img':'03.jpg'}, {'img':'04.jpg'},{'img':'05.jpg'},{'img':'06.jpg'},{'img':'07.jpg'}, {'img':'08.jpg'},{'img':'09.jpg'},{'img':'10.jpg'},{'img':'11.jpg'}, {'img':'12.jpg'},{'img':'13.jpg'},{'img':'14.jpg'},{'img':'15.jpg'}, {'img':'16.jpg'},{'img':'17.jpg'},{'img':'01.jpg'},{'img':'02.jpg'}, {'img':'03.jpg'},{'img':'04.jpg'},{'img':'05.jpg'},{'img':'06.jpg'}, {'img':'07.jpg'},{'img':'08.jpg'},{'img':'09.jpg'},{'img':'10.jpg'}, {'img':'11.jpg'},{'img':'12.jpg'},{'img':'13.jpg'},{'img':'14.jpg'}, ]; window.addEventListener('scroll',()=>{ if (checkLoading('box')){ //載入新的圖片 data.map((current)=>{ const newBox = document.createElement('div'); newBox.className = 'box'; parent.appendChild(newBox); const newPic = document.createElement('div'); newPic.className = 'pic'; newBox.appendChild(newPic); const newImg = document.createElement('img'); newImg.src = 'images/'+current.img; newPic.appendChild(newImg); }); imgLocation('box'); } }); } function checkLoading(child){ const content = getChilds(child); const lastTop = content[content.length - 1].offsetTop; const scrollTop = document.body.scrollTop || document.documentElement.scrollTop; const pageTop = document.body.clientHeight || document.documentElement.clientHeight; if ((scrollTop + pageTop > lastTop) ||(scrollTop == 0 && lastTop < pageTop)){ return true; } } function imgLocation(child){ const content = getChilds(child); const imgWidth = content[0].offsetWidth; const num = Math.floor(document.body.clientWidth / imgWidth); //讓圖片靈活居中 parent.style.cssText = 'width:'+ imgWidth * num + 'px;margin:0 auto;'; //計算圖片的高度 const heightArr = []; [].map.call(content,(current,index)=>{ if (index < num){ heightArr.push(current.offsetHeight); } else { //得到圖片的最小高度 const minHeight = Math.min(...heightArr); //得到最小高度的序列號 const minIndex = getMinIndex(minHeight,heightArr); current.style.position = 'absolute'; current.style.top = minHeight + 'px'; current.style.left = content[minIndex].offsetLeft + 'px'; //更新最小的高度 heightArr[minIndex] += current.offsetHeight; } }); } //將父級元素下的所有符合條件的子元素獲取 function getChilds(child){ const childArr = []; const tagsAll = parent.getElementsByTagName('*'); [].map.call(tagsAll,(current)=>{ if (current.className == child){ childArr.push(current); } }); return childArr; } function getMinIndex(minHeight,heightArr){ for (const i in heightArr){ if (minHeight == heightArr[i]){ return i; } } } window.addEventListener('load',WaterFall());
結果:執行成功。
程式設計的時候出現的報錯:
報錯1:Uncaught TypeError: Cannot read property 'getElementsByTagName' of null
原因:頁面的載入順序問題,將script新增到body的後面
報錯2:HTMLCollection []問題
原因:在獲取container下的所有節點的時候,const tagsAll = parent.getElementsByTagName('*'); 得到的是HTMLCollection,它不是陣列,會動態改變。
所以採用以下程式設計方法:
[].map.call(tagsAll,(current)=>{ if (current.className == child){ childArr.push(current); }
待完善的:
視窗大小改變的時候,在不用重新整理的情況下圖片自動更改適應瀑布流
使用ajax請求圖片資料
在點選相應的圖片的時候,背景變暗,被點選的圖片被放大。
非同步請求資料的時候,如果未知圖片的高度,怎麼辦?
移動端的優化。