最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

jquery實(shí)現(xiàn)簡(jiǎn)單的瀑布流布局

 更新時(shí)間:2016年12月11日 15:00:39   作者:葡萄美酒夜光杯  
瀑布流布局有兩種,一種是固定列,一種是非固定列。本文主要記述第一種的實(shí)現(xiàn)。需要的朋友可以參考借鑒

是開(kāi)頭都會(huì)說(shuō)的原理

瀑布流布局有兩種,一種是固定列,一種是非固定列。在此主要記述第一種的實(shí)現(xiàn)。

固定列的特征是:無(wú)論頁(yè)面如何縮放,每行的總列數(shù)都一致。

一行4列的瀑布流從布局的角度來(lái)說(shuō),就是4個(gè)li標(biāo)簽。通過(guò)一定的事件(比如滾動(dòng)條滾動(dòng)多少px),然后讀取之,再把數(shù)據(jù)動(dòng)態(tài)地添加到頁(yè)面中。

添加數(shù)據(jù)原則,不是根據(jù)li索引值來(lái)加,而是根據(jù)各列中高度最短的的那列動(dòng)態(tài)添加。否則可能導(dǎo)致頁(yè)面很難看(左右高度不統(tǒng)一)。

實(shí)例涉及ajax方法??稍诜?wù)器環(huán)境下運(yùn)行。

廢話不多說(shuō)了。直接上樣式。

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

基本效果如圖:

樣式顯示沒(méi)問(wèn)題之后,就把li里面的代碼刪掉。

接下來(lái)通過(guò)ajax來(lái)動(dòng)態(tài)添加。

數(shù)據(jù)哪里來(lái)?

這里用的是wookmark的數(shù)據(jù)接口。

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

點(diǎn)開(kāi)url得到是一個(gè)json。

信息量很大。怎么分析?

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

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

控制臺(tái)打印結(jié)果為:

原來(lái)是一個(gè)50個(gè)圖片信息組成的數(shù)組。每個(gè)數(shù)組元素都是一個(gè)json。在這個(gè)簡(jiǎn)單的demo里面,暫時(shí)只需要取preview屬性和title屬性就好了。

布局實(shí)現(xiàn)

關(guān)鍵之一在于,判斷最短的li,事實(shí)上我們需要最短高度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="'+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()])
 })
})

再加載看看,布局就出來(lái)了。簡(jiǎn)單又漂亮。

做到這里,看起來(lái)一切都挺好。然而潛伏著一個(gè)致命的問(wèn)題。

for循環(huán)惹的禍?

看看console.log的信息。為了分析,我把4個(gè)li的高度放進(jìn)了一個(gè)數(shù)組:

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

而到循環(huán)結(jié)束,程序判斷的終點(diǎn)竟然只有令人發(fā)指的1000多個(gè)px,因?yàn)閳D片加載過(guò)程慢于for循環(huán)執(zhí)行速度。雖然demo里的顯示還算正常,但這種代碼在網(wǎng)速不好時(shí),會(huì)造成工作事故。

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

可以用個(gè)定時(shí)器監(jiān)聽(tīng)下,然后用遞歸實(shí)現(xiàn),我的方案是這樣

   var index=0;
   function LoadPic(index){
   var $html=$('<div><img src="'+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監(jiān)聽(tīng)一次
   }
   LoadPic(0);

但是,從用戶體驗(yàn)的角度來(lái)說(shuō),等一張圖加載完成再進(jìn)行下一張加載是不友好的。數(shù)據(jù)提供方都應(yīng)該直接把圖片的高度在服務(wù)器處理好,json數(shù)據(jù)里面返回過(guò)來(lái)。網(wǎng)速很慢的時(shí)候,要等好久,然后一下子圖片都出來(lái)了,不覺(jué)得很詭異嗎?尤其是第三方接口。一加載不出來(lái)就出大問(wèn)題了。

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

因此for循環(huán)還是可以有的,在返回的數(shù)據(jù)里面,有寬度和高度值。利用它們就可以實(shí)現(xiàn)定寬(255px)和定高(原始高度乘上一個(gè)比例)。

$(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="'+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()])
 })
})

事實(shí)上個(gè)人認(rèn)為這是最簡(jiǎn)單且用戶體驗(yàn)最好的方案。

有了瀑布,還需要流

流的邏輯

往下拉(滾動(dòng)),第一個(gè)底部進(jìn)入可視區(qū)的li,優(yōu)先加載。

換句話說(shuō),最短li的高度與該li到頁(yè)面頂部之和小于滾動(dòng)條高度和可視區(qū)高度之和時(shí),觸發(fā)li加載。

li的高度好求。但是最短li到頁(yè)面頂部距離怎么求?

原生的方法可以這樣實(shí)現(xiàn):

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

但是本案例既然是用jquery,自然有它的方法。

obj.offset().top

滾動(dòng)事件

原生的實(shí)現(xiàn)方法是:window.onscroll=function(){...}

jquery的實(shí)現(xiàn)方法是:$(window).scroll(function(){...})

現(xiàn)在驗(yàn)證一下寫(xiě)出的代碼代碼有沒(méi)問(wèn)題

 (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到頁(yè)面頂部的高度之和<可視區(qū)高度+滾動(dòng)距離
 if($li.offset().top+$li.height()<document.documentElement.clientHeight+scrollTop){
  alert(1);
 }
 })

運(yùn)行代碼,發(fā)現(xiàn)第一個(gè)到底的li出現(xiàn)是可視區(qū)時(shí),彈出1.證明可用。

因?yàn)樯婕暗綕L動(dòng)事件,所以getJSON相關(guān)函數(shù)應(yīng)該封裝為getList()方便調(diào)用。所以需要重新調(diào)整一下。

此時(shí)的代碼是這樣的:

//找出高度最小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="'+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);
 }
 })
})

這樣一來(lái),好像可以實(shí)現(xiàn)了。但是一看控制臺(tái)的console.log,又發(fā)現(xiàn)問(wèn)題。

如廁的邏輯

在觸發(fā)加載前提時(shí),圖片正在加載,期間動(dòng)了滾動(dòng)條,就又觸發(fā)第二次加載,再動(dòng)一下,就觸發(fā)第三次,于是短短一瞬間,觸發(fā)了n次加載。

那就做一個(gè)開(kāi)關(guān)吧。

就跟公廁邏輯一樣。n個(gè)人排隊(duì)進(jìn)一個(gè)坑位。外面的人想要進(jìn)去首先得判斷門(mén)是否鎖上了。沒(méi)鎖才能進(jìn)。進(jìn)去之后第一件事把門(mén)鎖上。等如廁完畢,門(mén)就打開(kāi)。后面的人才能進(jìn)

新設(shè)置一個(gè)開(kāi)關(guān)bCheck,默認(rèn)為true。

到觸發(fā)加載條件時(shí),還要判斷bCheck是否為真(門(mén)開(kāi)),為真時(shí)才能觸發(fā)getList()(如廁)。否則return false(只能等)。

getList一開(kāi)始就把bCheck設(shè)為false(如廁前先鎖門(mén))。等到getList回調(diào)函數(shù)執(zhí)行到尾聲。再把bCheck設(shè)為true(開(kāi)門(mén))。

這一段不貼代碼了。

總有流完的一天。

當(dāng)數(shù)據(jù)結(jié)束時(shí)(所有人上完廁所),就沒(méi)有必要再進(jìn)行加載了(自動(dòng)把門(mén)鎖上)。

所以在getJSON回調(diào)函數(shù)內(nèi)鎖門(mén)之后發(fā)現(xiàn)進(jìn)來(lái)的是個(gè)空數(shù)組,那就進(jìn)行判斷,當(dāng)獲取到data的length為空時(shí),直接returnfalse。那么bCheck就永遠(yuǎn)關(guān)上了。

全部代碼如下:

//找出高度最小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="'+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到頁(yè)面頂部的高度之和<可視區(qū)高度+滾動(dòng)距離
 if($li.offset().top+$li.height()<document.documentElement.clientHeight+scrollTop){
  if(bCheck){
  bCheck=false;
  pageNum++;
  //console.log(pageNum);
  getList(pageNum); 
  }else{
  return false;
  } 
 }
 })
})

以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!

相關(guān)文章

  • jQuery動(dòng)態(tài)添加元素后元素注冊(cè)事件失效解決

    jQuery動(dòng)態(tài)添加元素后元素注冊(cè)事件失效解決

    這篇文章主要介紹了jQuery動(dòng)態(tài)添加元素后元素注冊(cè)事件失效解決,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08
  • jQuery簡(jiǎn)單操作cookie的插件實(shí)例

    jQuery簡(jiǎn)單操作cookie的插件實(shí)例

    這篇文章主要介紹了jQuery簡(jiǎn)單操作cookie的插件,以實(shí)例形式分析了jQuery操作cookie的插件功能定義與使用技巧,需要的朋友可以參考下
    2016-01-01
  • 自寫(xiě)的一個(gè)jQuery圓角插件

    自寫(xiě)的一個(gè)jQuery圓角插件

    下面介紹自己寫(xiě)的一個(gè)jQuery圓角的插件,功能非常簡(jiǎn)單。目前只能實(shí)現(xiàn)1px的固定弧度的圓角矩形邊框。
    2010-10-10
  • jQuery實(shí)現(xiàn)的購(gòu)物車物品數(shù)量加減功能代碼

    jQuery實(shí)現(xiàn)的購(gòu)物車物品數(shù)量加減功能代碼

    這篇文章主要介紹了jQuery實(shí)現(xiàn)的購(gòu)物車物品數(shù)量加減功能,涉及jQuery針對(duì)鼠標(biāo)事件的響應(yīng)及頁(yè)面元素動(dòng)態(tài)操作相關(guān)技巧,需要的朋友可以參考下
    2016-11-11
  • JQuery省市聯(lián)動(dòng)效果實(shí)現(xiàn)過(guò)程詳解

    JQuery省市聯(lián)動(dòng)效果實(shí)現(xiàn)過(guò)程詳解

    這篇文章主要介紹了JQuery省市聯(lián)動(dòng)效果實(shí)現(xiàn)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • jquery中使用ajax獲取遠(yuǎn)程頁(yè)面信息

    jquery中使用ajax獲取遠(yuǎn)程頁(yè)面信息

    當(dāng)我們點(diǎn)擊表格里面的標(biāo)題顯示相關(guān)的詳細(xì)信息,比如點(diǎn)擊新聞標(biāo)題顯示正文,而正文通常是在一個(gè)頁(yè)面里面,通過(guò)獲取傳遞的參數(shù)id查詢數(shù)據(jù)庫(kù),然后顯示出來(lái)
    2011-11-11
  • jQuery的remove()方法使用詳解

    jQuery的remove()方法使用詳解

    從DOM中刪除所有匹配的元素。這個(gè)方法不會(huì)把匹配的元素從jQuery對(duì)象中刪除,因而可以在將來(lái)再使用這些匹配的元素。但除了這個(gè)元素本身得以保留之外,其他的比如綁定的事件,附加的數(shù)據(jù)等都會(huì)被移除。我的理解就是將元素移除了。
    2015-08-08
  • jquery?操作DOM的基本用法分享

    jquery?操作DOM的基本用法分享

    jquery?操作DOM的基本用法分享,使用jquery的朋友可以參考下,方便以后對(duì)dom操作
    2012-04-04
  • 淺談jquery之on()綁定事件和off()解除綁定事件

    淺談jquery之on()綁定事件和off()解除綁定事件

    下面小編就為大家?guī)?lái)一篇淺談jquery之on()綁定事件和off()解除綁定事件。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-10-10
  • jquery validate.js表單驗(yàn)證的基本用法入門(mén)

    jquery validate.js表單驗(yàn)證的基本用法入門(mén)

    jquery.validate.js是jquery下的一個(gè)驗(yàn)證插件,功能比較強(qiáng)大,早就有所耳聞但是一只沒(méi)有動(dòng)手用過(guò),現(xiàn)在在于能夠研究一下了。
    2010-05-05

最新評(píng)論

行唐县| 遵化市| 都安| 锡林浩特市| 松原市| 琼海市| 兴业县| 曲水县| 沙雅县| 瑞丽市| 昭苏县| 武川县| 永德县| 蓝山县| 虞城县| 德清县| 霍城县| 慈利县| 嘉荫县| 沙湾县| 前郭尔| 六枝特区| 阳西县| 常州市| 雷山县| 眉山市| 黎城县| 新津县| 锦州市| 南宁市| 铜陵市| 北川| 荔波县| 专栏| 阜宁县| 龙门县| 丹凤县| 淳安县| 封开县| 台南县| 登封市|