代码: 两列图片瀑布流(一次后台取数据,无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="data:images/dd.png" data-src="data:images/_1.jpg"><p>aaaaa</p></a></div>
<div class="pin"><a class="box"><img src="data: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="data: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="data:images/dd.png" data-src="data:images/_2.jpg"><p>cccccccccc</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_3.jpg"><p>dddddddddddd</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_4.jpg"><p>eeeeeeeeeeee</p></a></div>
<div class="pin"><a class="box"><img src="data: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="data:images/dd.png" data-src="data:images/_1.jpg"><p>gggggg</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_2.jpg"><p>hhhhhhhhh</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_3.jpg"><p>iiiiiiiii</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_4.jpg"><p>jjjjjjjjj</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_5.jpg"><p>kkkkkkkkkk</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_1.jpg"><p>lllll</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_2.jpg"><p>mmmmmm</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_3.jpg"><p>nnnnnnnnnnn</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_1.jpg"><p>ooooooooooo</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_2.jpg"><p>ppppppppp</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_3.jpg"><p>qqqqqqqqqq</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_1.jpg"><p>rrrrrrrrrr</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_2.jpg"><p>sssssssss</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_3.jpg"><p>tttttttttttt</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_1.jpg"><p>uuuuuuuuuuu</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_2.jpg"><p>vvvv</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_3.jpg"><p>ww</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_1.jpg"><p>xxx</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data:images/_2.jpg"><p>yyyyyyyy</p></a></div>
<div class="pin"><a class="box"><img src="data:images/dd.png" data-src="data: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');
});
});
....