成人精品一区二区三区中文字幕-成人精品一区二区三区-成人精品一级毛片-成人精品亚洲-日本在线视频一区二区-日本在线视频免费

導航首頁 ? 技術教程 ? jquery實現簡單的瀑布流布局
全站頭部文字 我要出現在這里
jquery實現簡單的瀑布流布局 808 2024-02-09   

是開頭都會說的原理

瀑布流布局有兩種,一種是固定列,一種是非固定列。在此主要記述第一種的實現。

固定列的特征是:無論頁面如何縮放,每行的總列數都一致。

一行4列的瀑布流從布局的角度來說,就是4個li標簽。通過一定的事件(比如滾動條滾動多少px),然后讀取之,再把數據動態地添加到頁面中。

添加數據原則,不是根據li索引值來加,而是根據各列中高度最短的的那列動態添加。否則可能導致頁面很難看(左右高度不統一)。

實例涉及ajax方法。可在服務器環境下運行。

廢話不多說了。直接上樣式。

 <ul id="ul1">
 <li>
  <div>
  <img src="http://www.gimoo.net/t/1810/images/1.jpg">
  <p>我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述</p>
  </div>
 </li>
 <li>
  <div>
  <img src="http://www.gimoo.net/t/1810/images/2.jpg">
  <p>我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述</p>
  </div>
 </li>
 <li>
  <div>
  <img src="http://www.gimoo.net/t/1810/images/3.jpg">
  <p>我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述我是文字描述</p>
  </div>
 </li>
 <li>
  <div>
  <img src="http://www.gimoo.net/t/1810/images/4.jpg">
  <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;
}

基本效果如圖:

查看圖片

樣式顯示沒問題之后,就把li里面的代碼刪掉。

接下來通過ajax來動態添加。

數據哪里來?

這里用的是wookmark的數據接口。

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

點開url得到是一個json。

信息量很大。怎么分析?

一般可以看文檔。但是手頭沒有文檔的情況下,可以看看鏈接。返回是什么鬼。

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

控制臺打印結果為:

查看圖片

原來是一個50個圖片信息組成的數組。每個數組元素都是一個json。在這個簡單的demo里面,暫時只需要取preview屬性和title屬性就好了。

布局實現

關鍵之一在于,判斷最短的li,事實上我們需要最短高度li的索引值。

//找出高度最小li的索引值
function getShortestLi(){
 var shortest=0;
 for(var i=1;i<4;i++){
 if($('li').eq(i).height()<$('li').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=$('<div><img src="http://www.gimoo.net/t/1810/5bc58c71c3d96.html'+data[i].preview+'"><p>'+data[i].title+'</p></div>');
  //console.log($('li').eq(getShortestLi()).height())
  $('li').eq(getShortestLi()).append($html);
 };
 console.log([$('li').eq(0).height(),$('li').eq(1).height(),$('li').eq(2).height(),$('li').eq(3).height()])
 })
})

再加載看看,布局就出來了。簡單又漂亮。

查看圖片

做到這里,看起來一切都挺好。然而潛伏著一個致命的問題。

for循環惹的禍?

看看console.log的信息。為了分析,我把4個li的高度放進了一個數組:

查看圖片

50張圖片分4列,少說平均高度也得有三四千像素。

而到循環結束,程序判斷的終點竟然只有令人發指的1000多個px,因為圖片加載過程慢于for循環執行速度。雖然demo里的顯示還算正常,但這種代碼在網速不好時,會造成工作事故。

思路一:可以判斷圖片是否加載完成。

可以用個定時器監聽下,然后用遞歸實現,我的方案是這樣

   var index=0;
   function LoadPic(index){
   var $html=$('<div><img src="http://www.gimoo.net/t/1810/5bc58c71c3d96.html'+data[index].preview+'"><p>'+data[index].title+'</p></div>')
   $('li').eq(getShortestLi()).append($html);
   var oImg=$html.find('img');
   var t=setInterval(function(){
    if(oImg.height()!=0){//如果加載完了。
    clearInterval(t);
    //console.log([$('li').eq(0).height(),$('li').eq(1).height(),$('li').eq(2).height(),$('li').eq(3).height()])
    if(index<50){
     return LoadPic(index+1);
    }else{
     return false;
    } 
    }else{
    console.log('wait')
    }
   },50)//每隔50ms監聽一次
   }
   LoadPic(0);

但是,從用戶體驗的角度來說,等一張圖加載完成再進行下一張加載是不友好的。數據提供方都應該直接把圖片的高度在服務器處理好,json數據里面返回過來。網速很慢的時候,要等好久,然后一下子圖片都出來了,不覺得很詭異嗎?尤其是第三方接口。一加載不出來就出大問題了。

所幸的是,第三方提供了圖片的寬高信息。

因此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=$('<div><img src="http://www.gimoo.net/t/1810/5bc58c71c3d96.html'+data[i].preview+'"><p>'+data[i].title+'</p></div>')
  $('li').eq(getShortestLi()).append($html);
  
  $html.find('img').css('height',(data[i].height*225/data[i].width)+'px');
  $html.find('img').css('width','225px'); 
  };
 //console.log([$('li').eq(0).height(),$('li').eq(1).height(),$('li').eq(2).height(),$('li').eq(3).height()])
 })
})

事實上個人認為這是最簡單且用戶體驗最好的方案。

有了瀑布,還需要流

流的邏輯

往下拉(滾動),第一個底部進入可視區的li,優先加載。

查看圖片

換句話說,最短li的高度與該li到頁面頂部之和小于滾動條高度和可視區高度之和時,觸發li加載。

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=$('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()<document.documentElement.clientHeight+scrollTop){
  alert(1);
 }
 })

運行代碼,發現第一個到底的li出現是可視區時,彈出1.證明可用。

因為涉及到滾動事件,所以getJSON相關函數應該封裝為getList()方便調用。所以需要重新調整一下。

此時的代碼是這樣的:

//找出高度最小li的索引值
function getShortestLi(){
 var shortest=0;
 for(var i=1;i<4;i++){
 if($('li').eq(i).height()<$('li').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;i<data.length;i++){
  var $html=var $html=$('<div><img src="http://www.gimoo.net/t/1810/5bc58c71c3d96.html'+data[i].preview+'"><p>'+data[i].title+'</p></div>');
  //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()<document.documentElement.clientHeight+scrollTop){
  pageNum++;
  console.log(pageNum);
  getList(pageNum);
 }
 })
})

這樣一來,好像可以實現了。但是一看控制臺的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($('li').eq(i).height()<$('li').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;i<data.length;i++){  
  //console.log(data[i].preview);
  var $html=$('<div><img src="http://www.gimoo.net/t/1810/5bc58c71c3d96.html'+data[i].preview+'"><p>'+data[i].title+'</p></div>');
  $('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()<document.documentElement.clientHeight+scrollTop){
  if(bCheck){
  bCheck=false;
  pageNum++;
  //console.log(pageNum);
  getList(pageNum); 
  }else{
  return false;
  } 
 }
 })
})

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持綠夏網!



主站蜘蛛池模板: 舞出我的人生| 欲望中的女人电影| 查宁·塔图姆| 大森元贵| 文王一支笔的功效与作用| 白血公主| 个体工商户起名字大全免费| 广川| 婚变电视剧免费观看| 魔1983| 蛇谷奇兵 电影| 可爱的萝拉| 10元人民币图片| 王牌特派员| 1—42集分集剧情简介| 电影宝贝| 胎心监护多少周开始做| 日韩女同性恋| 速度与激情10免费观看完整电影| 帕巴拉呼图克图| 春闺梦里人电影在线观看| 久纱野水萌| 琉璃演员表全部演员介绍| 口述与子性细节过程| 少妇av片在线观看| 伊藤爱子| 妈妈的爱情房客 电影| 男操女视频免费| 买下我完整版电影免费观看| 我们的快乐人生 电视剧| 科室对分级护理落实情况检查记录| 情欲视频| 女孩们的周末| 大奉打更人电视剧在线播放视频| 男同视频在线| 天才gogogo综艺节目规则| 恶行之外电影完整在线观看| 被抛弃的青春1982| 但愿人长久| 婚前协议电视剧演员表| 泰国av|

?。。≌鹃L長期在線接?。?!

網站、小程序:定制開發/二次開發/仿制開發等

各種疑難雜癥解決/定制接口/定制采集等

站長微信:lxwl520520

站長QQ:1737366103