代碼: 兩列圖片瀑布流(一次后台取數據,無ajax,圖片懶加載。下拉后分批顯示圖片。圖片高度未知,當圖片onload后才顯示容器)
【思路】:
圖片瀑布流,網上代碼有多種實現方式,也有各類插件。沒找到合意的,所以根據網上找的一段代碼,進行了較大改動。
需引用 zepto 或 jquery。
我這個是應用於手機上的,兩列瀑布流,圖片高度未知——等圖片的onloaded事件觸發后,才對容器進行計算和定位。
大容器是 $("#imgList"),容器格子是$(".pin")
初始狀態下,php一次性生成全部容器格子的數據(大約幾十個吧。因為瀑布流不可能是無限制瀑布流,適可而止的呈獻給用戶合適數量的圖片就足以滿足需求了),不采用ajax。這樣代碼存在於真實的網頁源碼中,也適合seo。后台也不必單獨開發接口,易於管理。
$(this.aPin).addClass("hide").addClass("l");//初始化:先一次性將所有容器格子設為隱藏+左浮動。
滾動后觸發事件,只有容器格子中的圖片被加載后,容器格子才會移除隱藏狀態。
之后計算左列和右列已有的高度(圖片未載入完畢的容器格子為隱藏狀態,不計算),每一個新的容器格子,都追加到當前最短的一列。也就是添加樣式 .l 或 .r
WATERFALL.Timer :說一下這個定時器。圖片的onloaded事件會觸發很多次,為了避免載入每張圖片后,都將頁面重繪計算一次,所以加了個定時器作限制。(100毫秒后如無新圖載入,調用計算頁面位置的方法;有新圖載入,僅僅只刷新定時器)
其它參數可參考.js文件頁頭注釋
下面先談一下scroll事件,后面再給出正式代碼。
前言:我們先看一下scroll事件,調用得太頻繁了 (chrome中打開,用鼠標拉一下滾動條,看一下控制台)
<p>拿鼠標拖動一下滾動條,看看scroll事件觸發的有多么頻繁</p> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><hr> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><hr> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><hr> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><hr> <script src="http://cdn.bootcss.com/zepto/1.1.6/zepto.min.js"></script> <script type="text/javascript"> $(function(){ var WATERFALL = { scroll:function() {//發生滾動后,調用此方法 var curTime=new Date().getTime(); console.log(curTime); }, }; //------------------------正文-------------------------- //滾屏 $(window).scroll(function() { WATERFALL.scroll('#imgList','.pin'); }); }); </script>
所以需要對滾屏事件加一下限制:(增加了一個變量logTime,記載上一次滾動請求的時間) (這種廢棄,用下面那個)
var WATERFALL = { logTime:0,//最后一次滾屏操作的時間 checkscroll:function() { //兩次滾動請求之間時間需大於500毫秒,避免多次請求 var curTime=new Date().getTime(); if(this.logTime > (curTime-500) ){ return false; }else{ this.logTime = curTime; return true; } }, scroll:function() {//發生滾動后,調用此方法 if(this.checkscroll()){ var curTime=new Date().getTime(); console.log(curTime); } }, };
又一種降低頻繁請求的寫法:2015-11-19
<script type="text/javascript" src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script> <script type="text/javascript"> $(function(){ var timer; $(window).scroll(function () { clearTimeout(timer); timer = setTimeout(function () { console.log(new Date().getTime()); console.log($(document).scrollTop()); }, 100); }); }); </script>
正式代碼:
1.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>圖片瀑布流</title> <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="msapplication-tap-highlight" content="no"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="pragma" content="no-cache" /> </head> <body> <!-- 圖片瀑布流: start --> <div id="imgList"> <div class="pin"><a class="box" href="test2.html"><img src="images/dd.png" data-src="images/_1.jpg"><p>aaaaa</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="http://h.hiphotos.baidu.com/zhidao/pic/item/6a63f6246b600c3320b14bb3184c510fd8f9a185.jpg"><p>風景圖1</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="http://d.hiphotos.baidu.com/zhidao/pic/item/32fa828ba61ea8d34e62be55970a304e251f581b.jpg"><p>風景圖222</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_2.jpg"><p>cccccccccc</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_3.jpg"><p>dddddddddddd</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_4.jpg"><p>eeeeeeeeeeee</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="http://f4.topit.me/4/53/7e/11949842569497e534o.jpg"><p>ffffffff</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_1.jpg"><p>gggggg</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_2.jpg"><p>hhhhhhhhh</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_3.jpg"><p>iiiiiiiii</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_4.jpg"><p>jjjjjjjjj</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_5.jpg"><p>kkkkkkkkkk</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_1.jpg"><p>lllll</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_2.jpg"><p>mmmmmm</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_3.jpg"><p>nnnnnnnnnnn</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_1.jpg"><p>ooooooooooo</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_2.jpg"><p>ppppppppp</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_3.jpg"><p>qqqqqqqqqq</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_1.jpg"><p>rrrrrrrrrr</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_2.jpg"><p>sssssssss</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_3.jpg"><p>tttttttttttt</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_1.jpg"><p>uuuuuuuuuuu</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_2.jpg"><p>vvvv</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_3.jpg"><p>ww</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_1.jpg"><p>xxx</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_2.jpg"><p>yyyyyyyy</p></a></div> <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_3.jpg"><p>zzzz</p></a></div> </div> <!-- 圖片瀑布流: end --> <style type="text/css"> html,body,p{margin:0;padding:0;} body{background:#e8e8e8;} #imgList{position:relative;width:100%;overflow:auto;} #imgList > .hide{display:none;}/*初始化時 .pin 會被js設為隱藏*/ #imgList > .l{float:left;padding:10px 5px 0 10px;}/*左列*/ #imgList > .r{float:right;padding:10px 10px 0 5px;}/*右列*/ #imgList .pin{position:relative;width:50%;padding:10px 5px 0 10px;box-sizing: border-box;margin:0;} #imgList .box{display:block;background:#fff;padding:0;box-sizing:border-box;} #imgList .box > img{width:100%;height:auto;} #imgList .box > p{padding:14px 6px 14px 6px;font-size:14px;text-align:left;color:#333;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;} </style> <script src="http://cdn.bootcss.com/zepto/1.1.6/zepto.min.js"></script> <script type="text/javascript" src="waterfall.js"></script><!-- 瀑布流js --> </body> </html>
waterfall.js
$(function(){ /*** 【兩列圖片瀑布流(圖片高度未知)】 firstCounter:5,//設置:第一次加載幾張 limit:3,//設置每次加載幾張 cur:0,//當前第幾張 init()方法:初始化,將所有容器設為隱藏+左浮動 loadimg()方法:給每個圖片加onload事件,圖片載入后,觸發 waterfall()方法: 對瀑布流排序和定位(容器中如果圖片未載入完畢的,依舊隱藏。) checkscroll()方法: 滾動檢測 logTime變量: 兩次滾動加載請求之間時間需大於500毫秒,避免高頻率請求 scroll()方法: 發生滾動后,調用次方法 */ var WATERFALL = { oParent: "",// 父級對象名 aPin: "",// 存儲塊框pin的類名 logTime:0,//最后一次滾屏操作 Timer:null,//圖片載入后,加延遲定時器 firstCounter:8,//設置:第一次加載幾張 limit:3,//設置每次加載幾張 cur:0,//當前第幾張 init:function(parent,pin) {//初始化 this.oParent = parent; //parend 父級id this.aPin = pin; //pin 容器 $(this.aPin).addClass("hide").addClass("l");//初始化:先將所有容器設為隱藏+左浮動。 this.loadimg(0,this.firstCounter);//第一次載入的圖片 }, loadimg:function(_start,_end) { if(_end > $(this.aPin).length){_end = $(this.aPin).length;}//去掉超出總數的不合理數據 this.cur = _end; for(var i=_start;i<_end;i++){ var _aPin = $(this.aPin).eq(i); var _img = _aPin.find("img"); _img.attr("src",_img.attr("data-src")); //圖片load事件 _img.bind("load",function(){ var _aPin = $(this).parents( WATERFALL.aPin );//容器 _aPin.removeClass("hide");//圖片已載入后,顯示容器 console.log("-----圖片載入次序---"+_aPin.index()); //定時器(100毫秒后如無新圖載入,計算位置;有新圖載入,刷新定時器)——避免頻繁重復操縱頁面 clearTimeout(WATERFALL.Timer); WATERFALL.Timer = setTimeout(function(){ WATERFALL.waterfall(); }, 100);//100毫秒 }); } }, waterfall:function() { console.log("waterfall (圖片排序)----!!"); //左右列的當前累計總高度(不包含當前容器高) var _sumH1=0; var _sumH2=0; $(this.aPin).eq(0).addClass("l"); for(var i=0;i<$(this.aPin).length;i++){//遍歷數組aPin的每個塊框元素 var _aPin = $(this.aPin).eq(i); if(_aPin.hasClass("hide")==false){//判斷是否該容器的圖片已載入 var _sumH = _aPin.position().top + _aPin.height();//當前容器相對於父元素的偏移 + 當前元素高(為下一次循環准備數據) //_aPin.attr("data-sum1",_sumH1); //_aPin.attr("data-sum2",_sumH2); //_aPin.attr("data-h",_aPin.height()); if(i==0){ _sumH1 = _sumH; }else{ if(_sumH2>_sumH1){ _aPin.removeClass("r").addClass("l");//左列 _sumH1 = _sumH; }else{ _aPin.removeClass("l").addClass("r");//右列 _sumH2 = _sumH; } } } } }, checkscroll:function() { //兩次滾動請求之間時間需大於500毫秒,避免多次請求 var curTime=new Date().getTime(); if(this.logTime > (curTime-500) ){ return false; }else{ var oParent = $(this.oParent); var aPin = $(this.aPin); if(aPin.length==0){return false;}//空數據不作處理 var aPinLast = aPin.eq(this.cur-1);//最后一個顯示的容器 var lastPinH = aPinLast.offset().top + aPinLast.height()-10;//到最后一個容器的高度時,載入下一次 var scrollTop = $(document.body).scrollTop();//滾動高度 var windowH = $(window).height();//頁面高度 //console.log("lastPinH=" + lastPinH +", scrollTop="+scrollTop +"--- windowH:"+windowH+" >>> "+ (lastPinH - scrollTop -windowH ) ); if( (lastPinH - scrollTop -windowH ) < 0 ){//到達指定高度后 返回true,觸發waterfall()函數 this.logTime = curTime;//更新時間標記 //console.log("第"+this.cur+"個, 總共"+aPin.length+"個"); if(this.cur >= aPin.length){ return false; }else{ this.counter++; return true; } }else{ return false; } } }, scroll:function(parent,pin) {//發生滾動事件后,調用此方法 if(this.checkscroll()){ this.loadimg(this.cur,this.cur+this.limit);//每次需要新載入的圖片 } }, }; //------------------------正文-------------------------- //1.初始化 WATERFALL.init('#imgList','.pin'); //2.滾屏加載 $(window).scroll(function() { WATERFALL.scroll('#imgList','.pin'); }); });
....