>  기사  >  웹 프론트엔드  >  jquery는 간단한 폭포 흐름 레이아웃을 구현합니다.

jquery는 간단한 폭포 흐름 레이아웃을 구현합니다.

高洛峰
高洛峰원래의
2016-12-28 10:10:52958검색

은 처음에 언급한 원리입니다

폭포 흐름 레이아웃에는 두 가지 유형이 있는데, 하나는 고정 열이고 다른 하나는 비고정 열입니다. 이 문서에서는 주로 첫 번째 유형의 구현을 설명합니다.

고정 열의 특징은 페이지 크기가 어떻게 조정되든 각 행의 총 열 수가 일정하다는 것입니다.

레이아웃 관점에서 볼 때 행 1개와 열 4개로 구성된 폭포 흐름은 4개의 li 태그입니다. 특정 이벤트(예: 스크롤 막대가 스크롤되는 픽셀 수 등)를 통해 읽은 다음 페이지에 데이터를 동적으로 추가합니다.

데이터 추가의 원칙은 li 인덱스 값을 기준으로 추가하는 것이 아니라 컬럼 중 높이가 가장 짧은 컬럼을 기준으로 동적으로 추가하는 것입니다. 그렇지 않으면 페이지가 보기 흉할 수 있습니다(왼쪽 및 오른쪽 높이가 균일하지 않음).

예제는 ajax 방식을 사용합니다. 서버 환경에서 실행할 수 있습니다.

더 이상 말도 안되는 소리는 없습니다. 스타일을 직접 적용해 보세요.

<ul id="ul1">
 <li>
  <div>
   <img  src="images/1.jpg" alt="jquery는 간단한 폭포 흐름 레이아웃을 구현합니다." >
   <p>我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述</p>
  </div>
 </li>
 <li>
  <div>
   <img  src="images/2.jpg" alt="jquery는 간단한 폭포 흐름 레이아웃을 구현합니다." >
   <p>我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述</p>
  </div>
 </li>
 <li>
  <div>
   <img  src="images/3.jpg" alt="jquery는 간단한 폭포 흐름 레이아웃을 구현합니다." >
   <p>我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述</p>
  </div>
 </li>
 <li>
  <div>
   <img  src="images/4.jpg" alt="jquery는 간단한 폭포 흐름 레이아웃을 구현합니다." >
   <p>我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述</p>
  </div>
 </li>
</ul>

css

*{
 margin:0;
 padding: 0;
}
ul li{
 list-style: none;
}
#ul1{
 width: 1080px;
 margin: 100px auto 0;
}
li{
 width: 247px;
 float: left;
 margin-right: 10px;
}
li div{
 border:1px solid #000;padding:10px;
 margin-bottom:10px;
}
li div img{
 width: 225px;display: block;
}

기본 효과는 그림과 같습니다.

jquery는 간단한 폭포 흐름 레이아웃을 구현합니다.

스타일이 올바르게 표시된 후 , 삭제된 코드 내부의 li를 변경합니다.

다음으로 ajax를 통해 동적으로 추가합니다.

데이터는 어디서 나오나요?

여기서는 ookmark의 데이터 인터페이스가 사용됩니다.

http://www.wookmark.com/api/json/popular?page=1

URL을 클릭하면 json을 얻을 수 있습니다.

정보가 많아요. 분석하는 방법?

일반적으로 설명서를 보시면 됩니다. 하지만 문서가 없으면 링크를 볼 수 있습니다. 반환이란 도대체 무엇입니까?

function createUrl(num){
 return &#39;http://www.wookmark.com/api/json/popular?page=&#39;+num+&#39;&callback=?&#39;;
}
$(function(){
 $.getJSON(createUrl(1),function(data){
  console.log(data);
 })
})

콘솔 출력 결과는

jquery는 간단한 폭포 흐름 레이아웃을 구현합니다.

50개의 이미지 정보의 배열로 나옵니다. 각 배열 요소는 json입니다. 이 간단한 데모에서는 당분간 미리보기 속성과 제목 속성만 가져오면 됩니다.

레이아웃 구현의 핵심 중 하나

사실 가장 짧은 높이의 li 인덱스 값이 필요합니다.

//找出高度最小li的索引值
function getShortestLi(){
 var shortest=0;
 for(var i=1;i<4;i++){
  if($(&#39;li&#39;).eq(i).height()<$(&#39;li&#39;).eq(shortest).height()){
   shortest=i;
  }
 }
 return shortest;
}

그런 다음 getJSON 메소드

$(function(){
 $.getJSON(createUrl(1),function(data){
  //console.log(data);
  for(var i=0;i<dataArr.length;i++){
   var $html=$(&#39;<div><img  src="&#39;+data[i].preview+&#39;" alt="jquery는 간단한 폭포 흐름 레이아웃을 구현합니다." ><p>&#39;+data[i].title+&#39;</p></div>&#39;);
   //console.log($(&#39;li&#39;).eq(getShortestLi()).height())
   $(&#39;li&#39;).eq(getShortestLi()).append($html);
  };
  console.log([$(&#39;li&#39;).eq(0).height(),$(&#39;li&#39;).eq(1).height(),$(&#39;li&#39;).eq(2).height(),$(&#39;li&#39;).eq(3).height()])
 })
})

를 다시 로드하면 레이아웃이 나옵니다. 간단하고 아름답습니다.

jquery는 간단한 폭포 흐름 레이아웃을 구현합니다.

이 시점에서는 모든 것이 괜찮아 보입니다. 하지만 치명적인 문제가 숨어있습니다.

for 루프에 어떤 문제가 있나요?

console.log 정보를 보세요. 분석을 위해 4개의 li 높이를 배열에 넣었습니다.

50장의 사진을 4개의 열로 나누어 평균 높이는 최소한 3~4천 픽셀이 되어야 합니다.

루프가 끝나면 프로그램이 판단하는 끝점은 터무니없이 1,000픽셀에 불과합니다. for 루프 실행 속도보다 이미지 로딩 프로세스가 느리기 때문입니다. 데모에서는 정상적으로 표시되지만, 이러한 코드는 네트워크 속도가 좋지 않을 때 작업사고를 유발할 수 있습니다.

아이디어 1: 이미지가 로드되었는지 확인할 수 있습니다.

타이머를 사용하여 모니터링한 후 재귀를 사용하여 구현할 수 있습니다. 제 계획은 다음과 같습니다

var index=0;
function LoadPic(index){
 var $html=$(&#39;<div><img  src="&#39;+data[index].preview+&#39;" alt="jquery는 간단한 폭포 흐름 레이아웃을 구현합니다." ><p>&#39;+data[index].title+&#39;</p></div>&#39;)
 $(&#39;li&#39;).eq(getShortestLi()).append($html);
 var oImg=$html.find(&#39;img&#39;);
 var t=setInterval(function(){
  if(oImg.height()!=0){//如果加载完了。
   clearInterval(t);
   //console.log([$(&#39;li&#39;).eq(0).height(),$(&#39;li&#39;).eq(1).height(),$(&#39;li&#39;).eq(2).height(),$(&#39;li&#39;).eq(3).height()])
   if(index<50){
    return LoadPic(index+1);
   }else{
    return false;
   } 
  }else{
   console.log(&#39;wait&#39;)
  }
 },50)//每隔50ms监听一次
}
LoadPic(0);

단, 사용자 경험 측면에서 보면 그림이 나올 때까지 기다리세요. 로드됩니다. 다음 로드를 수행하는 것은 비우호적입니다. 데이터 제공자는 서버의 이미지 높이를 직접 처리하여 json 데이터로 반환해야 합니다. 인터넷 속도가 너무 느리면 오래 기다려야 하는데 갑자기 사진이 다 나오는 게 이상하지 않나요? 특히 타사 인터페이스. 로드에 실패하면 큰 문제가 발생합니다.

다행히 제3자가 이미지의 너비와 높이 정보를 제공합니다.

그래서 여전히 for 루프를 가질 수 있습니다. 반환된 데이터에는 너비와 높이 값이 있습니다. 이를 사용하면 고정 너비(255px)와 고정 높이(원래 높이에 비율을 곱함)를 얻을 수 있습니다.

$(function(){
 $.getJSON(createUrl(1),function(data){
  console.log(data);
  for(var i=0;i<data.length;i++){
    //console.log(data[i].preview);
    var $html=$(&#39;<div><img  src="&#39;+data[i].preview+&#39;" alt="jquery는 간단한 폭포 흐름 레이아웃을 구현합니다." ><p>&#39;+data[i].title+&#39;</p></div>&#39;)
    $(&#39;li&#39;).eq(getShortestLi()).append($html);
     
    $html.find(&#39;img&#39;).css(&#39;height&#39;,(data[i].height*225/data[i].width)+&#39;px&#39;);
    $html.find(&#39;img&#39;).css(&#39;width&#39;,&#39;225px&#39;); 
   };
  //console.log([$(&#39;li&#39;).eq(0).height(),$(&#39;li&#39;).eq(1).height(),$(&#39;li&#39;).eq(2).height(),$(&#39;li&#39;).eq(3).height()])
 })
})

사실 개인적으로 이것이 최고의 사용자 경험을 갖춘 가장 간단한 솔루션이라고 생각합니다.

폭포와 함께 흐름도 필요합니다

흐름의 논리

풀다운(스크롤)하고 맨 아래에 보이는 영역에 들어가는 첫 번째 리 먼저 로드됩니다.

jquery는 간단한 폭포 흐름 레이아웃을 구현합니다.

즉, 가장 짧은 리의 높이와 페이지 상단까지의 리의 높이의 합이 스크롤 막대와 시각적 영역의 높이에 따라 li 로딩이 트리거됩니다.

리의 높이는 쉽게 찾을 수 있습니다. 하지만 li에서 페이지 상단까지의 최단 거리를 찾는 방법은 무엇입니까?

네이티브 메소드는 다음과 같이 구현할 수 있습니다.

function getTop(obj){
 var iTop=0;
 while(obj){
  iTop+=obj.offsetTop;
  obj=obj.offsetParent;
 }//累加元素本身和自身所有父级高度偏移值
 return iTop;
}

그러나 이 경우는 jquery를 사용하기 때문에 자연스럽게 고유한 메소드를 갖게 됩니다.

obj.offset().top

스크롤 이벤트

기본 구현 방법은 다음과 같습니다: window.onscroll=function(){...}

jquery 구현 방법은 다음과 같습니다. $(window).scroll(function(){...})

이제 작성된 코드에 문제가 있는지 확인합니다

(window).scroll(function(){
 var $li=$(&#39;li&#39;).eq(getShortestLi());
 var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;
 //console.log([$li.offset().top+$li.height(),document.documentElement.clientHeight+scrollTop])
 //如果li高度与li到页面顶部的高度之和<可视区高度+滚动距离
 if($li.offset().top+$li.height()<document.documentElement.clientHeight+scrollTop){
   alert(1);
 }
})

실행 코드는 첫 번째 li가 가시 영역에 나타날 때 1이 팝업되어 사용 가능함을 증명하는 것을 찾습니다.

스크롤링 이벤트가 포함되므로 getJSON 관련 함수를 getList()로 캡슐화해야 호출이 쉬워집니다. 그래서 재조정이 필요합니다.

이때 코드는 이렇습니다.

//找出高度最小li的索引值
function getShortestLi(){
 var shortest=0;
 for(var i=1;i<4;i++){
  if($(&#39;li&#39;).eq(i).height()<$(&#39;li&#39;).eq(shortest).height()){
   shortest=i;
  }
 }
 return shortest;
}
function createUrl(num){
 return 'http://www.wookmark.com/api/json/popular?page='+num+'&callback=?';
}
function getList(n){
 $.getJSON(createUrl(n),function(data){
  //console.log(data);
  for(var i=0;ijquery는 간단한 폭포 흐름 레이아웃을 구현합니다.

'+data[i].title+'

'); //console.log(data[i].height); $('li').eq(getShortestLi()).append($html); dataArr[i].height*=225/dataArr[i].width; $html.find('img').css('height',dataArr[i].height+'px'); $html.find('img').css('width','225px'); }; } $(function(){ var pageNum=1; getList(pageNum); $(window).scroll(function(){ var $li=$('li').eq(getShortestLi(); var scrollTop=document.documentElement.scrollTop||document.body.scrollTop; if($li.offset().top+$li.height()

이렇게 하면 달성할 수 있을 것 같습니다. 그런데 console.log를 보니 또 다른 문제가 발견되었습니다.

화장실 가는 논리

在触发加载前提时,图片正在加载,期间动了滚动条,就又触发第二次加载,再动一下,就触发第三次,于是短短一瞬间,触发了n次加载。

那就做一个开关吧。

就跟公厕逻辑一样。n个人排队进一个坑位。外面的人想要进去首先得判断门是否锁上了。没锁才能进。进去之后第一件事把门锁上。等如厕完毕,门就打开。后面的人才能进

新设置一个开关bCheck,默认为true。

到触发加载条件时,还要判断bCheck是否为真(门开),为真时才能触发getList()(如厕)。否则return false(只能等)。

getList一开始就把bCheck设为false(如厕前先锁门)。等到getList回调函数执行到尾声。再把bCheck设为true(开门)。

这一段不贴代码了。

总有流完的一天。

当数据结束时(所有人上完厕所),就没有必要再进行加载了(自动把门锁上)。

所以在getJSON回调函数内锁门之后发现进来的是个空数组,那就进行判断,当获取到data的length为空时,直接returnfalse。那么bCheck就永远关上了。

全部代码如下:

//找出高度最小li的索引值
function getShortestLi(){
 var shortest=0;
 for(var i=1;i<4;i++){
  if($(&#39;li&#39;).eq(i).height()<$(&#39;li&#39;).eq(shortest).height()){
   shortest=i;
  }
 }
 return shortest;
}
function createUrl(num){
 return 'http://www.wookmark.com/api/json/popular?page='+num+'&callback=?';
}
var bCheck=false;
function getList(n){
 $.getJSON(createUrl(n),function(data){
  if(data.length==0){
   return false;
  }else{
   for(var i=0;ijquery는 간단한 폭포 흐름 레이아웃을 구현합니다.

'+data[i].title+'

'); $('li').eq(getShortestLi()).append($html); $html.find('img').css('height',(data[i].height*225/data[i].width)+'px'); $html.find('img').css('width','225px'); }; } bCheck=true; }); } $(function(){ var pageNum=1; getList(pageNum); $(window).scroll(function(){ var $li=$('li').eq(getShortestLi()); var scrollTop=document.documentElement.scrollTop||document.body.scrollTop; //console.log([$li.offset().top+$li.height(),document.documentElement.clientHeight+scrollTop]) //如果li高度与li到页面顶部的高度之和<可视区高度+滚动距离 if($li.offset().top+$li.height()

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持PHP中文网!

更多jquery는 간단한 폭포 흐름 레이아웃을 구현합니다.相关文章请关注PHP中文网!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
이전 기사:jquery 스크롤 막대 플러그인(사용자 정의 가능)다음 기사:jquery 스크롤 막대 플러그인(사용자 정의 가능)

관련 기사

더보기