在当前网页效果中,瀑布流已经成了一种图片展示的方式,最近项目中设计师也把这种风格应用到了版面中,故在此进行了封装,以便重复利用。
谈一下思路:瀑布流,顾名思义像瀑布一样的布局,可以分多列,各列之间图片高度可以互不相同。图片需要动态加载,加载的时机是当滚动条滚动时看一下各列最后一个元素其后是否空白或当各列最后一个元素进行可视区时,请求新的图片加载。
使用jquery.waterfall.js插件必须遵守的几条法则:
1.后台返回的报文必须是json格式且为JSON类型(不能是看着像json类型的字符串哟);
2.报文结构:{"success":true或false,"message":"成功",data:[]};
3.首次使用保证浏览器有滚动条,否则你怎么告诉浏览器向后台发请求呢?
4.此插件中用到了waterfallloading样式,你可以自己设计,看一下案例你就明白了,
如果等待图片的尺寸不是32*32你可以修改源码,这个我就不再赘述了
源码:
/*
* @url:请求地址
* @pageIndex: 请求页码
* @pageSize: 请求个数
* @autoLoad: 自动请求一次数据
* @sendFlag: 是否可以发送请求
* @callback: 回调函数,第1个参数:请求回的数组元素,第2个参数:请求数据的瀑布流容器
*/
(function($) {
var old = $.fn.waterfall;
$.fn.waterfall = function(option) {
var opt = {
url: '',
pageIndex: 0,
pageSize: 20,
autoLoad: true,
sendFlag: true,
callback: $.noop
},
that = this;
$.extend(opt, option);
if(!that.data('option')){
setOpt(opt);
$(window).on('scroll.waterfall.founder', onscrollfn);
}else{
setOpt(opt);
}
loadScroll(opt);
//为每个元素设置独立的option属性,防止引用类型共用问题
function setOpt(opt){
that.each(function() {
var clone = $.extend({}, opt);
$(this).data('option', clone);
});
}
//调用事件
function loadScroll(opt){
if (opt.autoLoad) {
$(window).trigger('scroll.waterfall.founder');
}
}
//滚动事件
function onscrollfn() {
that.each(function(i, v) {
var $last = $(v).children().eq(-1),
t = $(window).height() + $(window).scrollTop(),
option = $(v).data('option'),
wh = {
w: 32,
h: 32
},
$load = $('<div class="waterfallloading"></div>').css({
left: $(v).offset().left + ($(v).width() - wh.w) / 2 + 'px',
top: $(v).offset().top + $(v).height() - wh.h + 'px'
});
//无子元素,则其父元素替代
$last = $last.length == 0 ? $(v) : $last;
if ($last.offset().top < t && option.sendFlag) {
//禁止重发,并追加Load效果
$(v).data('option').sendFlag = false;
$(v).append($load);
$.post(option.url, {
pageIndex: option.pageIndex,
pageSize: option.pageSize,
r: $.now()
}, function(json) {
//修改发送标识,增加页码
$(v).data('option').sendFlag = json.success;
$(v).data('option').pageIndex = ++option.pageIndex;
if (option.callback && $.isFunction(option.callback)) {
option.callback(json, $(v));
}
}, 'json').fail(function(jqXHR, textStatus, errorThrown) {
throw new Error(errorThrown);
}).always(function() {
$(v).find('.waterfallloading').remove();
});
}
});
}
return that;
};
$.fn.waterfall.noConflict = function() {
$.fn.waterfall = old;
return this;
};
})(jQuery);
案例:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<style>
*{
margin:0;
padding:0;
}
ul{
list-style:none;
}
li{
box-sizing:border-box;
width:200px;
height:200px;
border:1px solid red;
float:left;
margin: 5px;
}
#div1{
width:630px;
margin:0 auto;
}
.waterfallloading{
width: 32px;
height: 32px;
background: url('loading.gif') no-repeat;
overflow: hidden;
}
</style>
</head>
<body>
<div id="div1">
<ul>
<li><img src="../1.png" /></li>
<li><img src="../1.png" /></li>
<li><img src="../1.png" /></li>
<li><img src="../1.png" /></li>
<li><img src="../1.png" /></li>
<li><img src="../1.png" /></li>
</ul>
</div>
<script src="../js/jquery-2.1.1.js"></script>
<script src="jquery.waterfall.js" type="text/javascript" charset="utf-8"></script>
<script>
//autoLoad:false则不会主动加载一次数据
$('#div1 > ul').waterfall({
url: 'waterfall.ashx',
pageIndex: 0,
pageSize: 20,
autoLoad: true,
callback: function(json,$c){
//你遍历每次滚动条滚动请求回来的json即可
//$c,即为发请求的确切jquery对象(比如:$('.abc'),在页面中会有多个,这里的$c是确切到底是第几个class="abc"的元素要请求内容)
});
</script>
</body>
</html>
等待图片: