之前用过许多插件,但是从未深究过他们是如何实现的。最近在读书,刚好想到这个问题,便研究了一下。结合之前做懒加载的经验,试着写一个原生的插件。记录在此。
实现过程
环境封装
将所有代码封装在一个立即执行的匿名函数中
这样可以模仿块级作用域,确保不会对环境造成污染。
定义插件功能 (1) 默认的配置对象
var options = { offset : 20, //距离屏幕底部一定距离开始加载 time : 100, //延迟时间 selector : '.z-lazyload', //需要懒加载的图片类名 realUrl : 'data-original' //真实地址特性名 };
同时定义了存放待加载图片和延迟标识的全局变量
(2) 定义插件的入口函数,主要逻辑的实现。
function ImageLazyload(opts) { if (opts) { for(var key in opts) { options[key] = opts[key]; } } getNode(); _delay();//避免首次加载未触发scroll事件,主动触发一次加载函数 window.addEventListener('scroll', _delay, false); }
(3) 功能函数的编写
暴露访问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(); 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 ; }; this .ImageLazyload = ImageLazyload; })();
参考:实现一个图片懒加载插件有多难 延申:原生JavaScript插件编写指南