写一个原生JS懒加载插件

作者 Zhs 日期 2016-10-22
写一个原生JS懒加载插件

之前用过许多插件,但是从未深究过他们是如何实现的。最近在读书,刚好想到这个问题,便研究了一下。结合之前做懒加载的经验,试着写一个原生的插件。记录在此。

实现过程

  1. 环境封装

    将所有代码封装在一个立即执行的匿名函数中

    (function () {
    //插件所有功能都写在这个函数下
    })();

​ 这样可以模仿块级作用域,确保不会对环境造成污染。

  1. 定义插件功能
    (1) 默认的配置对象

    var options = {
    offset : 20, //距离屏幕底部一定距离开始加载
    time : 100, //延迟时间
    selector : '.z-lazyload', //需要懒加载的图片类名
    realUrl : 'data-original' //真实地址特性名
    };

    同时定义了存放待加载图片和延迟标识的全局变量

    var imgList = [],delay;

    (2) 定义插件的入口函数,主要逻辑的实现。

    • 配置修改
    • 获取懒加载图片节点
    • 绑定滚动事件
    function ImageLazyload(opts) {
    if (opts) {
    for(var key in opts) {
    options[key] = opts[key];
    }
    }
    getNode();
    _delay();//避免首次加载未触发scroll事件,主动触发一次加载函数
    window.addEventListener('scroll', _delay, false);
    }

    (3) 功能函数的编写

    • 判断图片位置
    • 显示图片
    • 延迟函数
  2. 暴露访问API,把入口函数绑定到windows对象上。

    this.ImageLazyload = ImageLazyload;

完整代码

(function () {
//默认配置
var options = {
offset : 20,
time : 100,
selector : '.z-lazyload',
realUrl : 'data-original'
};
var imgList = [],delay;
//调用的主函数
function ImageLazyload(opts) {
if (opts) {
for(var key in opts) {
options[key] = opts[key];
}
}
getNode();
_delay();//避免首次加载未触发scroll事件,主动触发一次加载函数
window.addEventListener('scroll', _delay, false);
}
function _isShow(el) {
var coords = el.getBoundingClientRect();
return ( (coords.top >= 0||(coords.top+coords.height) >= 0) && coords.left >= 0 && coords.top <=((window.innerHeight || document.documentElement.clientHeight) + parseInt(options.offset)));
}

function _loadImage() {
for (var i = imgList.length; i--;) {
var el = imgList[i];
if (_isShow(el)) {
el.src = el.getAttribute(options.realUrl);
el.classList.remove(options.selector.substring(1));
imgList.splice(i, 1);
}
}
}

function _delay() {
if(delay){
clearTimeout(delay);
}
delay = setTimeout(function () {
_loadImage();
}, options.time);
}


function getNode() {
imgList = [];
var nodes = document.querySelectorAll(options.selector);
for (var i = 0, l = nodes.length; i < l; i++) {
imgList.push(nodes[i]);
}
nodes = null;
};
//暴露API(把属性添加到windows对象上)
this.ImageLazyload = ImageLazyload;
})();

参考:实现一个图片懒加载插件有多难
延申:原生JavaScript插件编写指南