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

導航首頁 ? 技術教程 ? jQuery實現瀑布流布局詳解(PC和移動端)
全站頭部文字 我要出現在這里
jQuery實現瀑布流布局詳解(PC和移動端) 625 2024-03-22   

瀑布流布局已成為當今非常普遍的圖片展示方式,無論是PC還是手機等移動設備上。這種布局圖片的樣式大概分為三種:等高等寬、等寬不等高、等高不等寬,接下來我們就最為普遍的等寬不等高形式來作為示例。

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

查看圖片

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

查看圖片

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

動手

首先我們將如下樣式的若干個單元寫進body中,并將“box”向左浮動:

<div class="box">
 <img class="img" src="http://www.gimoo.net/t/1904/resource/images/1.jpg" />
 <div class="desc">Description</div>
</div>
<div class="box">
 <img class="img" src="http://www.gimoo.net/t/1904/resource/images/2.jpg" />
 <div class="desc">Description</div>
</div>
<div class="box">
 <img class="img" src="http://www.gimoo.net/t/1904/resource/images/3.jpg" />
 <div class="desc">Description</div>
</div>

得到如下效果:

查看圖片

接下來:

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. 首先計算出在瀏覽器中一行能容納多少圖片 (num) ,注意這里用了outerWidth,當傳入true時會返回元素包括margin、padding、border全部盒模型屬性的尺寸;

2. 創建一個存儲每一列高度的數組 (columnHeightArr) ,該數組的長度即為num值;

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

查看圖片

可以看到雖然擺對了地方但是所有的圖片都放在同一個地方了,這是因為我們需要在擺放一張圖片后就要增加該列的高度:

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);
  }
});

結果正確:

查看圖片

注意:上面的代碼需要運行于window.onload方法里,因為只有當頁面中的圖片資源全部加載完畢后,其每張圖片的高度才會有效。

因此會有一些很嚴重的問題,當網絡不好的時候圖片沒有完全加載完成就會出現圖片展示不全高度缺失的情況,這點在移動端很明顯。而且當我們加載更多時,更難判斷新追加的圖片是否加載完成。

在實際生產中更不會有一開始就將圖片寫死在HTML中的情況,所以我們通常用以下的方式來做:

首先我們在獲得圖片地址時同時也需要獲取圖片的寬和高 ,這點對服務端后臺來說并不是什么難事,可以拜托后臺兄弟將圖片的寬高數據拼進JSON,傳遞給你;

*接下來介紹小技巧,非常實用,它能保證一個元素無論大小如何變化,比例始終保持一致。這個技巧尤其適用于移動端,因為元素為了響應式通常使用百分比的形式。

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

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

不設置高度,而是用padding“擠”出元素高度,而padding的百分比值都是基于父級容器的寬度。padding需要擠多少呢?就是寬度乘以高寬比(width和padding值均為百分比值),這就是我們為什么需要獲得圖片尺寸的原因。

效果:

查看圖片

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

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

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

查看圖片

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

懶加載

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

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

<div class="box box-item">
 <div class="img" data-src="http://www.gimoo.net/t/1904/resource/images/1.jpg"></div>
 <div class="desc">Description</div>
</div>

接下來我們編寫懶加載函數:

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 為圖片相對于瀏覽器窗口的相對高度,類似于position:fixed感覺。

通過條件進行判斷,只有當該圖片在瀏覽器窗口內(之上或之下都不行)時,將需要設置背景圖元素的 data-src 值展示出來,并刪除該屬性。

之后將最外層元素的 box-item 刪除,因為已經展示出來的圖片不需要再進行這些判斷,刪除了該類名下一次滾動時就不會獲取到已經展示過的元素,需要遍歷的次數就會越來越少,這樣能起到一個優化的作用。

該函數需要在你的元素已經append進頁面時調用,以及在滾動時調用:

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

滾動加載

說完了懶加載,再說說滾動加載。所謂滾動加載就是當頁面滾動到底部附近時加載新的圖片。我這里選擇的是滾動到高度最小的列底部時加載新的數據,你也可以根據自己的喜好來做判斷。

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

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

滾動加載也是在window的滾動事件中進行監聽,可以與懶加載一起進行:

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

說完了PC端,我們來說下手機端。其實原理是一樣的,只是從多列變成固定的兩列了。

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);
  }
});

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

查看圖片

最后有一點要注意,因為我們沒有像百度一樣用一個個列盒子去裝,而是用定位的方式。導致的問題是圖片元素的父級沒法自適應高度,如果你有相關的需求我們可以計算出所有列中最長的長度,并將這個值賦值給父容器的min-height屬性:

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

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

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="http://www.gimoo.net/t/1904/5cc414ea93bdc.html'+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();
 });

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



主站蜘蛛池模板: 女孩们在线观看| 山西少儿频道| 重启之极海听雷2免费版在线播放| 家庭理论电影| 马明威| 749局啥时候上映| 赖小子| 午间剧场| 萱草花二声部合唱谱| 赖小子在线观看完整视频高清| 洛克线| 1988年英国的白蛇传说| 大师兄 电影| 老男孩之猛龙过江 电影| 楼下的女邻居| 红灯区1996| 误杀2电影免费观看高清完整版| 王瑞琪| 詹妮弗康纳利的电影| 日韩欧美动作影片| 墨雨云间电视剧免费播放| sm在线| 魏凤| 《暗格里的秘密》免费观看| 叶子淳| 抖音网页版登录官网| 炊事班的故事演员名单| 幼儿歌曲颠倒歌| 在线播放的免费电影网站| 艳妇乳肉豪妇荡乳xxx| 黎小军| 禁忌的游戏| 诈欺游戏电影| 初三化学试卷| nina hartley| 缇可| 带圈序号1-50| 六年级下册语文书50页内容| 西藏藏语卫视| 假男假女| 恰纳卡莱之战完整版在线观看|

!!!站長長期在線接!!!

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

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

站長微信:lxwl520520

站長QQ:1737366103