欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

jQuery實(shí)現(xiàn)瀑布流布局詳解(PC和移動(dòng)端)

 更新時(shí)間:2020年09月01日 08:07:54   投稿:lijiao  
這篇文章非常全面的介紹了在PC和移動(dòng)端上jQuery實(shí)現(xiàn)瀑布流布局的詳細(xì)過(guò)程,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,對(duì)瀑布流布局感興趣的小伙伴們可以參考一下

瀑布流布局已成為當(dāng)今非常普遍的圖片展示方式,無(wú)論是PC還是手機(jī)等移動(dòng)設(shè)備上。這種布局圖片的樣式大概分為三種:等高等寬、等寬不等高、等高不等寬,接下來(lái)我們就最為普遍的等寬不等高形式來(lái)作為示例。

我們用百度圖片作為范例:

這就是PC端比較常見(jiàn)的瀑布流布局方式,接下來(lái)我們審查下元素看看百度圖片里面是如何布局:

可以看到,它里面實(shí)際是若干個(gè)等寬的列容器,通過(guò)計(jì)算將圖片push到不同的容器里。而本文介紹的展示方法是通過(guò)定位的方式,雖然最后布局展示的方式不同,但之前的算法都比較類似。

動(dòng)手

首先我們將如下樣式的若干個(gè)單元寫進(jìn)body中,并將“box”向左浮動(dòng):

<div class="box">
 <img class="img" src="./resource/images/1.jpg" />
 <div class="desc">Description</div>
</div>
<div class="box">
 <img class="img" src="./resource/images/2.jpg" />
 <div class="desc">Description</div>
</div>
<div class="box">
 <img class="img" src="./resource/images/3.jpg" />
 <div class="desc">Description</div>
</div>

得到如下效果:

接下來(lái):

var boxArr = $('.box'),
  num = Math.floor(document.body.clientWidth / boxArr.eq(0).outerWidth(true)),
 columnHeightArr = [];
columnHeightArr.length = num;
boxArr.each(function(index, item) {
 if (index < num) {
 columnHeightArr[index] = $(item).outerHeight(true);
 } else {
 var minHeight = Math.min.apply(null, columnHeightArr),
 minHeightIndex = $.inArray(minHeight,columnHeightArr);

 $(item).css({
 position: 'absolute',
 top: minHeight,
 left: boxArr.eq(minHeightIndex).position().left
 });
 }
}); 

以上代碼大意為:

1. 首先計(jì)算出在瀏覽器中一行能容納多少圖片 (num) ,注意這里用了outerWidth,當(dāng)傳入true時(shí)會(huì)返回元素包括margin、padding、border全部盒模型屬性的尺寸;

2. 創(chuàng)建一個(gè)存儲(chǔ)每一列高度的數(shù)組 (columnHeightArr) ,該數(shù)組的長(zhǎng)度即為num值;

3. 遍歷所有圖片,將第一行的圖片高度分別存入列高數(shù)組中 (columnHeightArr) ,從第二行開(kāi)始,首先計(jì)算出所有列中最小的高度 (minHeight) 以及最小高度所在的列 (minHeightIndex)。之后將第二行開(kāi)始的圖片定位在高度最小列的下面,效果如下:

可以看到雖然擺對(duì)了地方但是所有的圖片都放在同一個(gè)地方了,這是因?yàn)槲覀冃枰跀[放一張圖片后就要增加該列的高度:

var boxArr = $('.box'),
 num = Math.floor(document.body.clientWidth / boxArr.eq(0).outerWidth(true)),
 columnHeightArr = [];
columnHeightArr.length = num;

boxArr.each(function(index, item) {
  if (index < num) {
    columnHeightArr[index] = $(item).outerHeight(true);
  } else {
    var minHeight = Math.min.apply(null, columnHeightArr),
 minHeightIndex = $.inArray(minHeight, columnHeightArr);

    $(item).css({
   position: 'absolute',
   top: minHeight,
   left: boxArr.eq(minHeightIndex).position().left
 });

    columnHeightArr[minHeightIndex] += $(item).outerHeight(true);
  }
});

 結(jié)果正確: 

注意:上面的代碼需要運(yùn)行于window.onload方法里,因?yàn)橹挥挟?dāng)頁(yè)面中的圖片資源全部加載完畢后,其每張圖片的高度才會(huì)有效。

因此會(huì)有一些很嚴(yán)重的問(wèn)題,當(dāng)網(wǎng)絡(luò)不好的時(shí)候圖片沒(méi)有完全加載完成就會(huì)出現(xiàn)圖片展示不全高度缺失的情況,這點(diǎn)在移動(dòng)端很明顯。而且當(dāng)我們加載更多時(shí),更難判斷新追加的圖片是否加載完成。

在實(shí)際生產(chǎn)中更不會(huì)有一開(kāi)始就將圖片寫死在HTML中的情況,所以我們通常用以下的方式來(lái)做:

首先我們?cè)讷@得圖片地址時(shí)同時(shí)也需要獲取圖片的寬和高 ,這點(diǎn)對(duì)服務(wù)端后臺(tái)來(lái)說(shuō)并不是什么難事,可以拜托后臺(tái)兄弟將圖片的寬高數(shù)據(jù)拼進(jìn)JSON,傳遞給你;

*接下來(lái)介紹小技巧,非常實(shí)用,它能保證一個(gè)元素?zé)o論大小如何變化,比例始終保持一致。這個(gè)技巧尤其適用于移動(dòng)端,因?yàn)樵貫榱隧憫?yīng)式通常使用百分比的形式。

假如手機(jī)頁(yè)面中有一張圖片,其寬度要為屏幕的一半,高寬比為2:1,需要在任何分辨的手機(jī)上保持比例不變。如何做?給元素設(shè)置如下屬性:

.box {
 width: 50%;
 height: 0;
 padding-bottom: 100%;
}

不設(shè)置高度,而是用padding“擠”出元素高度,而padding的百分比值都是基于父級(jí)容器的寬度。padding需要擠多少呢?就是寬度乘以高寬比(width和padding值均為百分比值),這就是我們?yōu)槭裁葱枰@得圖片尺寸的原因。

效果:

可以看到在chrome手機(jī)模擬器中ipone4和腎6Plus的顯示效果是完全一樣的。在手機(jī)頁(yè)面中寬是固定的,而高會(huì)隨著頁(yè)面內(nèi)容的多少而變化,這個(gè)技巧利用元素padding百分比的值其實(shí)是基于其父級(jí)容器的寬,將高的值巧妙的轉(zhuǎn)化成與寬相關(guān)。

說(shuō)到現(xiàn)在可能有人終于忍不住要問(wèn)了,講了這么多和瀑布流有什么關(guān)系!簡(jiǎn)單就是一句話,我們要拋棄 img 標(biāo)簽,而采用背景圖的方式。為了使用背景圖,就得保持元素的比例永遠(yuǎn)與圖片保持一致。

通過(guò)這種方式,可以不用判斷圖片都加載完畢,直接產(chǎn)生一些與圖片同比例的div,再為其設(shè)置背景圖,如下:

這里比如最外層的box寬度為220px,里面的img元素寬度就可以為100%,高度就可以通過(guò)padding擠出了。 

懶加載

使用背景圖的方式還有好處那就是可以比較方便的實(shí)現(xiàn)懶加載。那什么是懶加載呢?就是當(dāng)元素在我們的視野中時(shí)才展示圖片,滾動(dòng)時(shí)屏幕下方的圖片并不展示,這可以很好的增加加載速度提升體驗(yàn)。

首先我們給最外層的box增加一個(gè)box-item類名(之后有用),將圖片url并不設(shè)置給backgroundImage屬性,而是賦給一個(gè)自定義屬性:data-src。

<div class="box box-item">
 <div class="img" data-src="./resource/images/1.jpg"></div>
 <div class="desc">Description</div>
</div>

接下來(lái)我們編寫懶加載函數(shù):

function lazyLoad() {
  var boxArr = $('.box-item');
  
  boxArr.each(function(index, item) {
    var viewTop = $(item).offset().top - $(window).scrollTop(),
 imgObj = $(item).find('.img');

 if ((viewTop < $(window).height()) && (($(item).offset().top + $(item).outerHeight(true)) > $(window).scrollTop())) {
   imgObj.css('backgroundImage','url('+imgObj.attr("data-src")+')').removeClass('data-src');
   $(item).removeClass('box-item');
 }
 })
}

首先我們獲取所有擁有 .box-item 類名的元素,遍歷。viewTop 為圖片相對(duì)于瀏覽器窗口的相對(duì)高度,類似于position:fixed感覺(jué)。

通過(guò)條件進(jìn)行判斷,只有當(dāng)該圖片在瀏覽器窗口內(nèi)(之上或之下都不行)時(shí),將需要設(shè)置背景圖元素的 data-src 值展示出來(lái),并刪除該屬性。

之后將最外層元素的 box-item 刪除,因?yàn)橐呀?jīng)展示出來(lái)的圖片不需要再進(jìn)行這些判斷,刪除了該類名下一次滾動(dòng)時(shí)就不會(huì)獲取到已經(jīng)展示過(guò)的元素,需要遍歷的次數(shù)就會(huì)越來(lái)越少,這樣能起到一個(gè)優(yōu)化的作用。

該函數(shù)需要在你的元素已經(jīng)append進(jìn)頁(yè)面時(shí)調(diào)用,以及在滾動(dòng)時(shí)調(diào)用:

lazyLoad();
$(window).scroll(lazyLoad);

滾動(dòng)加載

說(shuō)完了懶加載,再說(shuō)說(shuō)滾動(dòng)加載。所謂滾動(dòng)加載就是當(dāng)頁(yè)面滾動(dòng)到底部附近時(shí)加載新的圖片。我這里選擇的是滾動(dòng)到高度最小的列底部時(shí)加載新的數(shù)據(jù),你也可以根據(jù)自己的喜好來(lái)做判斷。

function scrollLoad() {
  var viewHeight = $(window).scrollTop() + $(window).height(),
 minHeight = Math.min.apply(null, columnHeightArr);

  if (viewHeight >= minHeight) {
   //loadMore...
  }
}

滾動(dòng)加載也是在window的滾動(dòng)事件中進(jìn)行監(jiān)聽(tīng),可以與懶加載一起進(jìn)行:

$(window).scroll(function() {
 scrollLoad();
 lazyLoad(); 
});

說(shuō)完了PC端,我們來(lái)說(shuō)下手機(jī)端。其實(shí)原理是一樣的,只是從多列變成固定的兩列了。

var boxArr = $('.box'),
 columnHeightArr = [];
columnHeightArr.length = 2;

boxArr.each(function(index, item) {
  if (index < 2) {
    columnHeightArr[index] = $(item).outerHeight(true);
  } else {
    var minHeight = Math.min.apply(null, columnHeightArr),
 minHeightIndex = $.inArray(minHeight, columnHeightArr);

    $(item).css({
   position: 'absolute',
   top: minHeight,
   left: boxArr.eq(minHeightIndex).position().left
 });

    columnHeightArr[minHeightIndex] += $(item).outerHeight(true);
  }
});

不同的是為了適應(yīng)不同屏幕的手機(jī),最外層的box容器寬度和邊距要設(shè)置成百分比的形式。

 最后有一點(diǎn)要注意,因?yàn)槲覀儧](méi)有像百度一樣用一個(gè)個(gè)列盒子去裝,而是用定位的方式。導(dǎo)致的問(wèn)題是圖片元素的父級(jí)沒(méi)法自適應(yīng)高度,如果你有相關(guān)的需求我們可以計(jì)算出所有列中最長(zhǎng)的長(zhǎng)度,并將這個(gè)值賦值給父容器的min-height屬性:

$('body').css('minHeight',Math.max.apply(null, columnHeightArr)); 

整理下完整的代碼,瀑布流的全套服務(wù)就到這了

var dataArr = [
 {picUrl:'./resource/images/1.jpg',width:522,height:783},
 {picUrl:'./resource/images/2.jpg',width:550,height:786},
 {picUrl:'./resource/images/3.jpg',width:535,height:800},
 {picUrl:'./resource/images/4.jpg',width:578,height:504},
 {picUrl:'./resource/images/5.jpg',width:1440,height:900}
 ];

 $.each(dataArr, function(index, item) {
 $("body").append('<div class="box box-item">' +
 '<div class="img" style="height:0;padding-bottom:'+cRate(item) * 100 + "%"+'" data-src="'+item.picUrl+'"></div>' +
 '<div class="desc">Description</div>' +
 '</div>');
 });

 var boxArr = $('.box'),
 num = Math.floor(document.body.clientWidth / boxArr.eq(0).outerWidth(true)),
 columnHeightArr = [];
 columnHeightArr.length = num;
 
 arrangement();

  $('body').css('minHeight',Math.max.apply(null, columnHeightArr));

 lazyLoad();

 function arrangement() {
 boxArr.each(function(index, item) {
 if (index < num) {
 columnHeightArr[index] = $(item).outerHeight(true);
 } else {
 var minHeight = Math.min.apply(null, columnHeightArr),
 minHeightIndex = $.inArray(minHeight, columnHeightArr);
 $(item).css({
 position: 'absolute',
 top: minHeight,
 left: boxArr.eq(minHeightIndex).position().left
 });
 columnHeightArr[minHeightIndex] += $(item).outerHeight(true);
 }
 });
 }

 function lazyLoad() {
 var boxArr = $('.box-item');
 boxArr.each(function(index, item) {
 var viewTop = $(item).offset().top - $(window).scrollTop(),
 imgObj = $(item).find('.img');
 if ((viewTop < $(window).height()) && ($(item).offset().top + $(item).outerHeight(true) > $(window).scrollTop())) {
// console.log($(item).attr('data-src'));
 imgObj.css('backgroundImage','url('+imgObj.attr("data-src")+')').removeClass('data-src');
 $(item).removeClass('box-item');
 }
 })
 }

 function cRate(obj) {
 return obj.height / obj.width;
 }

 function scrollLoad() {
 var viewHeight = $(window).scrollTop() + $(window).height(),
 minHeight = Math.min.apply(null, columnHeightArr);
 if (viewHeight >= minHeight) {
 //loadMore...
 }
 }

 $(window).scroll(function() {
 lazyLoad();
 scrollLoad();
 });

以上就是為大家分享的關(guān)于jQuery瀑布流布局,內(nèi)容很豐富,需要大家一點(diǎn)點(diǎn)的理解消化,真正的做到學(xué)以致用,希望能夠幫助到大家。

相關(guān)文章

  • jquery DOM操作 基于命令改變頁(yè)面

    jquery DOM操作 基于命令改變頁(yè)面

    jquery DOM操作 基于命令改變頁(yè)面,需要的朋友可以參考下。
    2010-05-05
  • jQuery中的AjaxSubmit使用講解

    jQuery中的AjaxSubmit使用講解

    最近使用ajaxform有點(diǎn)頻繁,今天小編抽時(shí)間給大家記錄下有關(guān)jquery中的ajaxSubmit使用講解的知識(shí),非常不錯(cuò),感興趣的朋友參考下吧
    2016-09-09
  • jQuery的context屬性用法實(shí)例

    jQuery的context屬性用法實(shí)例

    這篇文章主要介紹了jQuery的context屬性用法,實(shí)例分析了context屬性返回節(jié)點(diǎn)內(nèi)容的使用技巧,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2014-12-12
  • Jquery中的CheckBox、RadioButton、DropDownList的取值賦值實(shí)現(xiàn)代碼

    Jquery中的CheckBox、RadioButton、DropDownList的取值賦值實(shí)現(xiàn)代碼

    隨著Jquery的作用越來(lái)越大,使用的朋友也越來(lái)越多。在Web中,由于CheckBox、 Radiobutton 、 DropDownList等控件使用的頻率比較高,就關(guān)系到這些控件在Jquery中的操作問(wèn)題
    2011-10-10
  • jQuery實(shí)現(xiàn)的個(gè)性化返回底部與返回頂部特效代碼

    jQuery實(shí)現(xiàn)的個(gè)性化返回底部與返回頂部特效代碼

    這篇文章主要介紹了jQuery實(shí)現(xiàn)的個(gè)性化返回底部與返回頂部特效代碼,涉及jQuery結(jié)合動(dòng)畫(huà)函數(shù)響應(yīng)鼠標(biāo)事件動(dòng)態(tài)改變頁(yè)面元素樣式的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-10-10
  • jQuery中:contains選擇器用法實(shí)例

    jQuery中:contains選擇器用法實(shí)例

    這篇文章主要介紹了jQuery中:contains選擇器用法,以實(shí)例形式分析了:contains選擇器的功能、定義及匹配給定元素文本時(shí)的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2014-12-12
  • jQuery使用$.ajax提交表單完整實(shí)例

    jQuery使用$.ajax提交表單完整實(shí)例

    這篇文章主要介紹了jQuery使用$.ajax提交表單的方法,以完整實(shí)例形式分析了jQuery基于ajax數(shù)據(jù)提交的具體步驟與數(shù)據(jù)處理技巧,非常簡(jiǎn)單實(shí)用,代碼備有詳盡的注釋便于理解,需要的朋友可以參考下
    2015-12-12
  • EasyUI,點(diǎn)擊開(kāi)啟編輯框,并且編輯框獲得焦點(diǎn)的方法

    EasyUI,點(diǎn)擊開(kāi)啟編輯框,并且編輯框獲得焦點(diǎn)的方法

    這篇文章主要介紹了EasyUI,點(diǎn)擊開(kāi)啟編輯框,并且編輯框獲得焦點(diǎn)的方法,需要的朋友可以參考下
    2015-03-03
  • jQuery實(shí)現(xiàn)用方向鍵控制層的上下左右移動(dòng)

    jQuery實(shí)現(xiàn)用方向鍵控制層的上下左右移動(dòng)

    本文將會(huì)使用jquery實(shí)現(xiàn)以下功能:按下方向鍵時(shí),使層向相應(yīng)的方向平滑移動(dòng)20像素;四個(gè)方向鍵的鍵碼分別是37(左)、38(上)、39(右)和40(下),感興趣的朋友可以了解下
    2013-01-01
  • jQuery validate插件功能與用法詳解

    jQuery validate插件功能與用法詳解

    這篇文章主要介紹了jQuery validate插件功能與用法,結(jié)合實(shí)例形式詳細(xì)分析了jQuery validate插件的功能、參數(shù)、使用方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2016-12-12

最新評(píng)論