實現思路:圖片寬度必定,高度不一樣,下一行的第一張圖片放在高度最小的圖片的下方,以此類推。css
實現代碼:html
html代碼:jquery
<!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代碼:ajax
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 app
緣由:頁面的加載順序問題,將script添加到body的後面 異步
報錯2:HTMLCollection []問題 優化
緣由:在獲取container下的全部節點的時候,const tagsAll = parent.getElementsByTagName('*'); 獲得的是HTMLCollection,它不是數組,會動態改變。spa
因此採用如下編程方法:
[].map.call(tagsAll,(current)=>{ if (current.className == child){ childArr.push(current); }
待完善的:
窗口大小改變的時候,在不用刷新的狀況下圖片自動更改適應瀑布流
使用ajax請求圖片數據
在點擊相應的圖片的時候,背景變暗,被點擊的圖片被放大。
異步請求數據的時候,若是未知圖片的高度,怎麼辦?
移動端的優化。