/*
*
* 图片懒加载:scrollLoad
*
*/
var scrollLoad = (function() {
var defaults = {
scrollBox: window, //滚动的容器
dataset: 'src', //'data-src'
debounceDelay: 260, //防抖动(当停止滚动并且超过260ms后才会触发相应代码)
imgList: [], //图片列表(可通过返回的接口进行后期维护)
load: function(e) {} //图片load回调
};
var merging = function(defaults, params) { //参数与默认值合并
var temp = {};
for (var i in defaults) {
if (defaults.hasOwnProperty(i)) {
temp[i] = params[i] === undefined ? defaults[i] : params[i];
}
}
if (temp.scrollBox === document || temp.scrollBox === document.documentElement || temp.scrollBox === document.body) {
temp.scrollBox = window;
}
return temp;
};
var debouncer = function(func, time) { //防抖动
var context, args, id;
return function() {
context = this;
args = arguments;
if (id) clearTimeout(id);
id = setTimeout(function() {
func.apply(context, args);
}, time);
};
};
var checkView = function(img, params) { //图片可视区(容器区)检验
var inY, inX, bCR = img.getBoundingClientRect();
if (bCR.height && bCR.width) {
inY = bCR.top - params.scrollBoxTop - params.scrollBoxH < 0 && bCR.bottom - params.scrollBoxTop > 0;
inX = bCR.left - params.scrollBoxLeft - params.scrollBoxW < 0 && bCR.right - params.scrollBoxLeft > 0;
}
return !!(inY && inX);
};
var imgOnLoad = function(img, params) { //图片加载事件
var src = img.dataset[params.dataset];
var _img = document.createElement('img');
_img.onload = function() {
var fLoad = function() {
params.load.apply(img, arguments);
this.removeEventListener('load', fLoad);
}
img.addEventListener('load', fLoad);
img.setAttribute('src', src);
this.onload = null;
};
_img.setAttribute('src', src);
};
return function(params) {
params = merging(defaults, params);
params.imgList = [].slice.call(params.imgList); //对外接口:转为数组
params.imgList.push = function() { //对外接口:push变异,拉平NodeList
var _push = [].push;
for (var i = 0; i < arguments.length; i++) {
if (arguments[i] instanceof NodeList) {
for (var j = 0; j < arguments[i].length; j++) {
_push.call(this, arguments[i][j]);
}
} else {
_push.call(this, arguments[i]);
}
}
return this;
}.bind(params.imgList);
params.imgList.clearUp = function() { //对外接口:从列表中清除已被remove的缓存元素
for (var item, i = 0; i < this.length; i++) {
item = this[i];
if ((item && item.nodeName) === 'IMG') {
if (!document.body.contains(item)) {
this.splice(i, 1);
i--;
}
}
}
return this;
}.bind(params.imgList);
params.imgList.unque = function() { //对外接口:去重
var result = [];
this.forEach(function(el, i, arr) {
if (arr.indexOf(el) === i) result.push(el);
});
this.splice(0, this.length);
for (var i = 0; i < result.length; i++) {
this[i] = result[i];
}
return this;
}.bind(params.imgList);
var loading = function() {
if (params.scrollBox === window) {
params.scrollBoxH = document.documentElement.clientHeight;
params.scrollBoxW = document.documentElement.clientWidth;
params.scrollBoxTop = 0;
params.scrollBoxLeft = 0;
} else {
var _bCR = params.scrollBox.getBoundingClientRect();
var _cStyle = window.getComputedStyle(params.scrollBox);
params.scrollBoxH = params.scrollBox.clientHeight;
params.scrollBoxW = params.scrollBox.clientWidth;
params.scrollBoxTop = _bCR.top + parseInt(_cStyle.borderTopWidth);
params.scrollBoxLeft = _bCR.left + parseInt(_cStyle.borderLeftWidth);
}
var list = params.imgList;
for (var item, i = 0; i < list.length; i++) {
item = list[i];
if ((item && item.nodeName) !== 'IMG') {
list.splice(i, 1);
i--;
} else if (checkView(item, params)) {
imgOnLoad(item, params);
list.splice(i, 1);
i--;
}
}
};
params.scrollBox.addEventListener('scroll', debouncer(loading, params.debounceDelay));
loading();
return params.imgList; //返回列表进行后期维护
};
})();
//使用情况
var imgList = scrollLoad({
imgList: document.querySelectorAll('img'),
load: function() {
this.classList.add('loaded', 'fade-in-300');
}
});
imgList.push(imgElement | imgNodeList); //后期维护:动态的添加元素到列表
imgList.clearUp(); //后期维护:从列表中清除已被remove的缓存元素
imgList.unque(); //后期维护:去重
imgList.push(imgElement | imgNodeList).clearUp().unque(); //链式写法