폭포 흐름에 대해 먼저 알아보겠습니다
폭포 흐름, 폭포 흐름 레이아웃이라고도 합니다. 비교적 인기 있는 웹 사이트 페이지 레이아웃입니다. 시각적 성능은 페이지 스크롤 막대가 아래로 스크롤됨에 따라 데이터 블록을 지속적으로 로드하고 현재 꼬리에 추가합니다. 이 레이아웃을 채택한 최초의 웹사이트는 Pinterest였으며, 이는 점차 국내에서 인기를 얻었습니다. Meilishuo 및 Taobao와 같은 중국의 최신 웹사이트 대부분은 기본적으로 이 스타일을 사용합니다.
이것은 제가 달성한 효과입니다. 즉, 아무리 스크롤해도 로드되지 않습니다. 그냥 폭포처럼 흐르고 흐르세요!
여기에서는 Js 구현 방법에 대해서만 이야기합니다
구현 원칙:
컨테이너에 있는 기존 데이터 블록 요소를 처음으로 계산합니다. 1. 컨테이너의 전체 너비 2. 열 너비 3. 열의 최소 수를 얻은 후 배열을 사용하여 모든 높이를 저장합니다. 상자의 최소 높이를 구합니다. 그런 다음 일련 번호를 기반으로 높이가 업데이트됩니다. 다소 어색해 보이지만 구현하기는 매우 간단합니다.
스크롤 로딩의 경우: 즉, 높이까지 스크롤한 후 데이터를 로드해야 합니다. 실제로 이는 열의 최소 높이 값입니다. 이런 식으로 현재 스크롤 값과 최소 높이 값을 비교할 수 있습니다. 데이터 로드를 트리거할지 여부를 결정합니다. 즉, 이미지 로드 조건이 충족되는지 확인하는 함수를 작성합니다. 예를 들어 마지막 그림의 offsetTop, 시각적 영역 높이, 스크롤 거리를 가져옵니다. 즉, 그림의 offsetTop이 시각적 영역 높이와 스크롤 거리의 합보다 작은 경우 이때 로드되어야 합니다. , 그러나 조건은 임의로 결정될 수 있습니다. 그림과 같이 로딩 조건을 트리거하기 전에 그림이 반쯤 스크롤될 때까지 기다릴 수도 있습니다.
HTML CSS 코드를 먼저 입력하세요
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>waterfall</title> <script src="script.js"></script> <style> * { margin: 0; padding: 0; } body { background: yellow; } #container { } #container .pin { padding-left: 15px; padding-top: 15px; float: left; } #container .div-box { float: left; border: 1px solid #ccc; box-shadow: 0 0 5px #bbb; background: #fff; padding: 12px; border-radius: 9px; } #container .div-box img { width: 300px; } #container .div-box p { text-align: center; font-size: 20px; font-weight: bold; color: red; } </style> <script> </script> </head> <body> <div id="container"> <div class="pin"> <div class="div-box"> <img src="img/1.jpg" alt=""> <p>白超华-博客园</p> </div> </div> <div class="pin"> <div class="div-box"> <img src="img/2.jpg" alt=""> <p>白超华-博客园</p> </div> </div> <div class="pin"> <div class="div-box"> <img src="img/3.jpg" alt=""> <p>白超华-博客园</p> </div> </div> <div class="pin"> <div class="div-box"> <img src="img/4.jpg" alt=""> <p>白超华-博客园</p> </div> </div> <div class="pin"> <div class="div-box"> <img src="img/5.jpg" alt=""> <p>白超华-博客园</p> </div> </div> <div class="pin"> <div class="div-box"> <img src="img/6.jpg" alt=""> <p>白超华-博客园</p> </div> </div> <div class="pin"> <div class="div-box"> <img src="img/7.jpg" alt=""> <p>白超华-博客园</p> </div> </div> <div class="pin"> <div class="div-box"> <img src="img/8.jpg" alt=""> <p>白超华-博客园</p> </div> </div> <div class="pin"> <div class="div-box"> <img src="img/9.jpg" alt=""> <p>白超华-博客园</p> </div> </div> <div class="pin"> <div class="div-box"> <img src="img/10.jpg" alt=""> <p>白超华-博客园</p> </div> </div> <div class="pin"> <div class="div-box"> <img src="img/1.jpg" alt=""> <p>白超华-博客园</p> </div> </div> <div class="pin"> <div class="div-box"> <img src="img/2.jpg" alt=""> <p>白超华-博客园</p> </div> </div> <div class="pin"> <div class="div-box"> <img src="img/3.jpg" alt=""> <p>白超华-博客园</p> </div> </div> <div class="pin"> <div class="div-box"> <img src="img/4.jpg" alt=""> <p>白超华-博客园</p> </div> </div> <div class="pin"> <div class="div-box"> <img src="img/5.jpg" alt=""> <p>白超华-博客园</p> </div> </div> <div class="pin"> <div class="div-box"> <img src="img/6.jpg" alt=""> <p>白超华-博客园</p> </div> </div> </div> </body> </html>
JS 코드, 각 줄에는 주석이 있습니다
window.onload = function(){ var data = { //模拟后台数据 的一个JSON格式的文件 "data":[ {"src":"1.jpg"}, {"src":"2.jpg"}, {"src":"3.jpg"}, {"src":"4.jpg"}, {"src":"5.jpg"}, ] }; window.onscroll = function(){ if(checkScroll()){ //判断是否具备滚动加载得条件 var oParent = document.getElementById('container'); for(var i=0; i<data.data.length; i++){ var div1 = document.createElement('div'); //创建div元素 div1.className = 'pin'; //设置class oParent.appendChild(div1); var div2 = document.createElement('div');//创建div元素 div2.className = 'div-box'; div1.appendChild(div2); var imgs = document.createElement('img');//创建img元素 imgs.style.width = '300px'; imgs.src = 'img/'+data.data[i].src; //设置读取路径 div2.appendChild(imgs); var p = document.createElement('p');//创建p元素 p.innerHTML = '白超华-博客园'; div2.appendChild(p); } waterfall('container','pin'); //--注意 别忘了这句,当滚动时候就执行 } } waterfall('container','pin'); } function waterfall(parent, box){ var oParent = document.getElementById(parent);//获取父级对象 var aBox = getByClass(oParent,box);//获取所有class为pin的盒子的集合 var boxWidth = aBox[0].offsetWidth;//获取一个盒子的宽 var pageWidth = document.body.clientWidth||document.documentElement.clientWidth;//获取可视区宽 var cols = Math.floor(pageWidth/boxWidth);//获得列数 var arrH = [];//用于存放盒子的高 for(var i=0; i<aBox.length; i++){ if(i<cols){//当小于第一列个数的时候 arrH.push(aBox[i].offsetHeight); } else { var minH = Math.min.apply(null,arrH);//得到数组中盒字的最小高度minH; var index = getMinIndex(arrH,minH); aBox[i].style.position = 'absolute';//设置绝对定位 aBox[i].style.top = minH+'px';//设置top,就是最小高度 aBox[i].style.left = aBox[0].offsetWidth*index+'px';//设置left,就是一个盒子的宽*index索引数 arrH[index]+=aBox[i].offsetHeight; //更新新添加盒字后的列高 } } } //通过父级获取class function getByClass(parent, classname){ var aClass = parent.getElementsByTagName('*'); var arr = []; for(var i=0; i<aClass.length; i++){ if(aClass[i].className == classname){ arr.push(aClass[i]); } } return arr; } //最小值的索引index function getMinIndex(arr,val){ for( i in arr){ if(arr[i] == val){ return i; } } } // function checkScroll(){ var oParent = document.getElementById('container'); var aBox = getByClass(oParent,'pin'); var lastBoxHeight = aBox[aBox.length-1].offsetTop;// 当滚到到这个距离时候就开始加载 var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;//兼容的滚动距离 var documentHeight = document.documentElement.clientHeight; //页面高度 if(lastBoxHeight<scrollTop+documentHeight){ return true; } }
위 내용은 이 글의 전체 내용입니다. 모든 분들의 공부에 도움이 되었으면 좋겠습니다.