ajax插件
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>图片瀑布流</title> <link rel="stylesheet" href="css/index.css" /></head><body> <div class="wrap js_box"></div> <script src="js/utils.js"></script> <script src="js/index.js"></script> <script type="text/javascript"> new Waterfall('js_box', { imgApi: 'server/index.php', column: 8, gap: 10 }).init(); </script></body></html>
;
(function (doc) {
var Waterfall = function (wrapper, opt) {
console.log(wrapper);
this.oWrapper = doc.getElementsByClassName(wrapper)[0];
this.column = opt.column;
this.gap = opt.gap;
this.imgApi = opt.imgApi;
this.itemWidth = (this.oWrapper.offsetWidth - (this.column - 1) * this.gap) / this.column;
this.pageNum = 0;
this.pageSize = 0;
this.heightArr = [];
}
Waterfall.prototype = {
init: function () {
this.getImgDatas(this.pageNum);
this.bindEvent();
},
bindEvent: function () {
console.log(this);
// 这里的bindthis原因:scrollToBottom在Waterfall的原型链上 window要使用scrollToBottom 方法 必须绑定 scrollToBottom的this指向否则无法使用?
window.addEventListener('scroll', this.scrollToBottom.bind(this), false);
},
scrollToBottom: function () {
// 滚到底部页码+1
if (getScrollTop() + getWindowHeight() == getScrollHeight()) {
this.pageNum++;
// 如果还有数据则再次渲染
// 页码下标从0开始所以比较条件< 页数-1
if (this.pageNum <= this.pageSize - 1) {
this.getImgDatas(this.pageNum);
}
}
},
getImgDatas: function (pageNum) {
var _self = this;
xhr.ajax({
url: this.imgApi,
type: 'POST',
dataType: 'JSON',
data: {
pageNum: pageNum
},
success: function (data) {
if (data != 'NO DATA') {
console.log(data);
var pageData = JSON.parse(data.pageData);
_self.pageSize = parseInt(data.pageSize);
_self.renderList(pageData, _self.pageNum);
}
}
})
},
renderList: function (data, pageNum) {
var _self = this,
oItems = null,
minIdx = -1;
data.forEach(function (elem, idx) {
var oItem = doc.createElement('div'),
oImg = new Image(),
// oTitle = doc.createElement('div'),
// 设置第元素的左边距第一列为0 其他的列:下标*(元素宽度+边距)
itemLeft = (idx + 1) % _self.column === 1 ? '0' : idx * (_self.itemWidth + _self.gap);
oItem.className = 'wf-item';
oItem.style.width = _self.itemWidth + 'px';
// 元素高度:旧高度*新计算出的宽度/旧宽度+要留的间隙
oItem.style.height = (elem.height * _self.itemWidth / elem.width) + 'px';
oImg.src = elem.img;
// oTitle.innerHTML = '<p>测试文本</p>';
// oTitle.className = 'title-box';
oItem.appendChild(oImg);
// oItem.appendChild(oTitle);
_self.oWrapper.appendChild(oItem);
oItems = doc.getElementsByClassName('wf-item');
// 设置第一页的左边距与上边距
if (idx < _self.column && pageNum == 0) {
_self.heightArr.push(oItem.offsetHeight);
oItem.style.top = '0';
oItem.style.left = itemLeft + 'px';
} else {
// 找出高度最小的元素
minIdx = getMinIdx(_self.heightArr);
// 左边距:与当前找出的高度最小元素一致
oItem.style.left = oItems[minIdx].offsetLeft + 'px';
// 上边距:当前找出的高度最小元素 + 需要间隔的上边距
oItem.style.top = (_self.heightArr[minIdx] + _self.gap) + 'px';
// 当前元素的高度加上新增元素+间隔的上边距;
_self.heightArr[minIdx] += (oItems[idx].offsetHeight + _self.gap);
}
oImg.style.opacity = '1';
});
}
}
function getMinIdx(arr) {
// 1.先找最小高度 2.找到位置
return [].indexOf.call(arr, Math.min.apply(null, arr));
}
window.Waterfall = Waterfall;
})(document);