写法一:对象写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>瀑布流+懒加载+jasonp —— 思路1</title>
<script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js"></script>
<style>
html, body, ul, li, p {
margin: 0;
padding: 0;
}
ul, li {
list-style: none;
}
.ct {
position: relative;
padding: 10px;
margin: 0 auto;
}
.clearfix:after {
content: '';
display: block;
clear: both;
}
.ct .item {
background: #fff;
width: 200px;
position: absolute;
padding: 0 0 10px 0;
box-shadow: 2px 2px 2px #E8E8E8, -2px -2px 2px #E8E8E8;
border: 1px solid #DFDFDF;
margin: 10px;
transition: all 1s;
}
.ct .item a {
display: block;
}
.ct .item img {
/* margin: 12px;
width: 176px; */
display: block;
width: 100%;
box-sizing: border-box;
padding: 10px;
}
.ct .item .header {
padding-bottom: 10px;
margin: 0 12px;
border-bottom: 1px solid #DBDBDB;
}
.ct .desp {
font-size:12px;
line-height: 1.8;
margin: 10px 15px 0;
color: #777371;
}
#load {
visibility: hidden;
}
</style>
</head>
<body>
<div class="ct-waterfall">
<ul id="pic-ct" class="ct clearfix">
<!-- <li class="item">
<a href="#" class="link">
<img src="" alt="">
</a>
<h4 class="header"></h4>
<p class="desp"></p>
</li> -->
</ul>
<div id="load">隐藏标记位</div>
</div>
<script>
/*
var Exposure = {
init: function($target, handler){
this.$c = $(window);
this.$target = $target;
this.handler = handler;
this.bind();
this.checkShow();
},
bind: function(){
var me = this,
clock = null,
interval = 100;
$(window).on('scroll', function(clock){
if(clock){
clearTimeout(clock);
}
clock = setTimeout(function(){
me.checkShow();
}, interval);
});
},
checkShow: function(){
var me = this;
this.$target.each(function(){
var $cur = $(this);
if(me.isShow($cur)){
if(me.handler){
me.handler.call(this);
}
}
});
},
isShow: function($el){
var scrollH = this.$c.scrollTop(),
winH = this.$c.height(),
top = $el.offset().top;
if(winH + scrollH > top){
return true;
} else {
return false;
}
}
}
*/
var Exposure = {
init: function($target, handler){
this.$target = $target;
this.handler = handler;
this.clock = null;
this.bind();
this.checkShow();
},
bind: function(){
var that = this;
$(window).on('scroll', function(){
if(that.clock){
clearTimeout(that.clock);
}
that.clock = setTimeout(function(){
that.checkShow();
}, 300);
});
},
isShow: function(target){
console.log(1);
var top = target.offset().top,
$winH = $(window).height(),
$scrollH = $(window).scrollTop;
console.log(top, $winH, $scrollH);
if(top < $winH + $scrollH){
return true;
} else {
return false;
}
},
checkShow: function(){
console.log(1);
if(this.isShow(this.$target)){
this.handler();
}
}
}
var waterFall = {
// arrHeight: [],
init: function($ct){
this.$ct = $ct;
this.arrHeight = [];
this.bind();
this.start();
},
bind: function(){
var me = this;
$(window).on('resize', function(){
me.start();
});
},
start: function($nodes){
var me = this;
this.$items = this.$ct.find('.item');
if(this.$items.length === 0) return;
this.$ctWidth = this.$ct.width();
console.log(this.$ctWidth);
this.itemWidth = this.$items.outerWidth(true);
this.colNum = Math.floor(this.$ctWidth / this.itemWidth);
this.$ct.width(this.itemWidth * this.colNum);
console.log(this.$ct.width());
console.log(this.itemWidth);
console.log(this.colNum);
if(this.arrHeight.length === 0 || !$nodes){
this.arrHeight = [];
for(var i=0; i<this.colNum; i++){
this.arrHeight[i] = 0;
}
}
if($nodes){
console.log(this.arrHeight.length);
$nodes.each(function(){
var $item = $(this);
$item.find('img').load(function(){
me.placeItem($item);
me.$ct.height(Math.max.apply(this, me.arrHeight));
});
});
} else {
this.$items.each(function(){
var $item = $(this);
me.placeItem($item);
});
console.log(me.arrHeight);
me.$ct.height(Math.max.apply(this, me.arrHeight));
}
},
placeItem: function($el){
var o = this.getIndexOfMin(this.arrHeight),
idx = o.idx,
min = o.min;
$el.css({
left: this.itemWidth * idx,
top: min //y轴放置最小arr[i]
});
// console.log(o, idx, min, this.itemWidth);
this.arrHeight[idx] += $el.outerHeight(true);
},
getIndexOfMin: function(arr){
var idx = 0,
min = arr[0];
for(var i=0; i<arr.length; i++){
if(arr[i] < min){
idx = i;
min = arr[i];
}
}
return {
idx: idx,
min: min
};
}
}
var lock = false,
page = 1,
pageCount = 30;
function getData(callback){
console.log(page);
if(lock){
return; //起始状态为false,所以不会执行if语句
}
lock = true; //上锁,禁止滚动
$.ajax({
url: 'http://platform.sina.com.cn/slide/album_tech',
type: 'get',
dataType: 'jsonp',
jsonp: 'jsoncallback',
data: {
app_key: '1271687855',
format: 'json',
size: 'img',
page: page,
num: pageCount
},
success: function(ret){
console.log(ret);
lock = false; //请求到数据,此时解锁变为可以滚动
if(ret.status.code == 0){
callback(ret.data);
page++;
console.log(page);
}
},
error: function(){
lock = false; //发生错误是,变为解锁状态可以滚动,可以继续执行请求数据
}
});
}
/*一开始是false 所以return不跳出,
给lock设置为true,这时候发送请求,请求返回结果之前,
lock一直都是true 所以这时候你要是往死里划,一直都是跳出函数
当请求成功了,lock设置为false,这时候一切和一开始一样了,可以继续发请求了*/
function renderData(items){
var $nodes,
im = '';
for(var i=0; i<items.length; i++){
im += '<li class="item">';
im += ' <a href="#" class="link"><img src="' + items[i].img_url + '"alt=""></a>';
im += ' <h4 class="header">' + items[i].short_name + '</h4>';
im += ' <p class="desp">' + items[i].short_intro + '</p>';
im += '</li>';
}
$nodes = $(im);
$('#pic-ct').append($nodes);
return $nodes;
console.log($nodes);
}
$(function(){
waterFall.init($('#pic-ct'));
Exposure.init($('#load'), function(){
getData(function(data){
console.log(1);
var $nodes = renderData(data);
waterFall.start($nodes);
console.log(1);
});
});
});
</script>
</body>
</html>
写法二:原型写法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>瀑布流+懒加载+jasonp —— 思路2</title>
<style type="text/css">
html,
body,
ul,
li,
p,
div {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul,
li {
list-style: none;
}
a {
text-decoration: none;
}
.clearfix:after {
content: '';
clear: both;
display: block;
}
.wrap {
width: 900px;
margin: 0 auto;
}
.pic-ct {
position: relative;
}
.pic-ct .item {
position: absolute;
padding-bottom: 10px;
width: 280px;
margin: 10px;
border: 1px solid #eee;
opacity: 0;
transition: all 0.8s;
}
.pic-ct .item img {
margin: 10px;
width: 260px;
}
.pic-ct .item .header {
margin: 0 12px;
height: 25px;
border-bottom: 1px solid #eee;
}
.pic-ct .item .des {
margin: 10px 15px 0;
color: #333;
font-size: 12px;
line-height: 1.8;
}
.btn {
display: inline-block;
visibility: hidden;
padding: 20px 40px;
border-radius: 3px;
font-size: 18px;
font-weight: bold;
background: #fed136;
cursor: pointer;
}
.hide {
display: none;
}
</style>
</head>
<body>
<div class="wrap">
<ul class="pic-ct clearfix">
<!-- <li class="item hide"></li> -->
</ul>
<div id="load" class="btn">Load More</div>
</div>
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
function Addmore($node) {
console.log(this)
this.getData();
this.click($node);
this.perPageCount = 9;
this.curPage = 1;
this.clock = null;
this.list = $node.find('.pic-ct');
}
Addmore.prototype = {
getData: function () {
var that = this;
$.ajax({
url: 'http://platform.sina.com.cn/slide/album_tech',
dataType: 'jsonp', //这里使用了新浪新闻的 jsonp 接口,大家可以直接看数据, 如: http://platform.sina.com.cn/slide/album_tech?jsoncallback=func&app_key=1271687855&num=3&page=4
jsonp: "jsoncallback",
data: {
app_key: '1271687855',
num: this.perPageCount,
page: this.curPage
}
}).done(function (ret) {
console.log(ret);
that.place(ret);
that.curPage++;
}).fail(function () {
alert('获取数据失败');
});
},
checkShow: function() {
if(this.isShow($('#load'))) {
console.log(1);
this.getData();
}
},
click: function ($node) {
var that = this;
$(window).on('scroll', function () {
if(that.clock){
clearTimeout(that.clock);
}
that.clock = setTimeout(function(){
that.checkShow();
}, 300);
});
},
isShow: function ($el) {
var scrollH = $(window).scrollTop(),
winH = $(window).height(),
top = $el.offset().top;
if (top < winH + scrollH) {
return true;
} else {
return false;
}
},
renderData: function (res) {
var str = '';
for (var i = 0; i < res.data.length; i++) {
str += '<li class="item">';
str += ' <a class="portfolio-link" href="javascript:void(0)">';
str += ' <div class="portfolio-hover"><i class="fa fa-plus"></i></div>';
str += ' <img src="' + res.data[i].img_url + '" alt="roundicons">';
str += ' </a>';
str += ' <div class="portfolio-desp">';
str += ' <h3>' + res.data[i].short_name + '</h3>';
str += ' <p class="text-muted">' + res.data[i].short_intro + '</p>';
str += ' </div>';
str += '</li>';
}
// console.log(str);
var $nodes = $(str);
this.list.append($nodes);
return $nodes;
},
//延迟组件。让页面代码同时渲染
place: function (ret) {
console.log(ret);
var $nodes = this.renderData(ret),
deferreds = [];
$nodes.find('img').each(function () {
var defer = $.Deferred();
$(this).on('load', function () {
defer.resolve(); //deferred.resolve():解决Deferred(延迟)对象,并根据给定的args参数调用任何完成回调函数(doneCallbacks)
});
deferreds.push(defer);
});
$.when.apply(null, deferreds).done(function () { //jQuery.when():提供一种方法来执行一个或多个对象的回调函数, Deferred(延迟)对象通常表示异步事件。
new Waterfall($('.wrap'));
});
}
};
function Waterfall($node) {
this.$node = $node;
this.init();
}
Waterfall.prototype = {
init: function () {
this.render(this.$node);
this.bind(this.$node);
},
bind: function ($node) {
var that = this;
$(window).on('resize', function () {
that.render($node);
});
},
render: function ($node) {
var ctWidth = $node.find('.pic-ct').width();
var $item = $node.find('.pic-ct li');
var itemWidth = $item.outerWidth(true);
var colNum = parseInt(ctWidth / itemWidth);
var colSumHeight = [];
for (var i = 0; i < colNum; i++) {
colSumHeight.push(0);
}
$item.each(function () {
var $cur = $(this);
var idx = 0,
minSumHeight = colSumHeight[idx];
for (var j = 0; j < colSumHeight.length; j++) {
if (colSumHeight[j] < minSumHeight) {
idx = j;
minSumHeight = colSumHeight[idx];
}
}
$cur.css({
top: minSumHeight,
left: itemWidth * idx,
opacity: 1
});
colSumHeight[idx] += $cur.outerHeight(true);
});
$node.find('.pic-ct').css({
height: Math.max.apply(null, colSumHeight)
});
}
};
new Addmore($('.wrap'));
</script>
</body>
</html>
网友评论