阿富

web前端

导航

【图片懒加载】scrollLoad

/*
 *
 * 图片懒加载: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(); //链式写法

 

posted on 2017-03-13 02:31  阿富  阅读(154)  评论(0)    收藏  举报