html5中文学习网

您的位置: 首页 > 网络编程 > 其它综合 » 正文

实现一个图片懒加载插件有多难? – 前端有多难? – SegmentFault-

[ ] 已经帮助:人解决问题

Web 图片的懒加载就是通过读取img元素,然后获得img元素的data-src(也可以约定为其他属性名)属性的值,并赋予img的src,从而实现动态加载图片的机制。JwGHTML5中文学习网 - HTML5先行者学习网

这里需要注意的是: img在初始化的时候不要设置src属性,因为即使设置 src='' 浏览器也会尝试加载图片。JwGHTML5中文学习网 - HTML5先行者学习网

一个简单的图片懒加载共涉及两个方面,JwGHTML5中文学习网 - HTML5先行者学习网

1. HTML 约定

我们首先需要给准备实施懒加载的img元素添加指定的class 这里为m-lazyload ,同时将img src赋值给 data-src属性。JwGHTML5中文学习网 - HTML5先行者学习网
具体示例为:JwGHTML5中文学习网 - HTML5先行者学习网

<img class="m-lazyload" data-src="imgUrl">

2. JavaScript 实现

动态加载总共分为以下几个步骤,这里每个步骤都将被拆分为独立的函数JwGHTML5中文学习网 - HTML5先行者学习网

1. 添加页面滚动监听事件
window.addEventListener('scroll', _delay, false);function _delay() {  clearTimeout(delay);  delay = setTimeout(function () {    _loadImage();  }, time);}
2. 当触发监听事件时会执行 _loadImage 函数,该函数负责加载图片
function _loadImage() {  for (var i = imgList.length; i--;) {    var el = imgList[i];    if (_isShow(el)) {      el.src = el.getAttribute('data-src');      el.className = el.className.replace(new RegExp("(//s|^)" + _selector.substring(1, _selector.length) + "(//s|$)"), " ");      imgList.splice(i, 1);    }  }}

虽然执行了_loadImage函数,但是我们得知道哪些图片需要被加载,这里的判断依据是什么呢?JwGHTML5中文学习网 - HTML5先行者学习网

依据就是判断该图片是否在当前窗口的可视区域内,在这里我们封装一个_isShow函数来实现JwGHTML5中文学习网 - HTML5先行者学习网

function _isShow(el) {  var coords = el.getBoundingClientRect();  return ( (coords.top >= 0 && coords.left >= 0 && coords.top) <= (window.innerHeight || document.documentElement.clientHeight) + parseInt(offset));}

自此一个图片加载的闭环就形成了JwGHTML5中文学习网 - HTML5先行者学习网

当网页滚动的事件被触发 -> 执行加载图片操作 -> 判断图片是否在可视区域内 -> 在,则动态将data-src的值赋予该图片。JwGHTML5中文学习网 - HTML5先行者学习网

太简单了?

事实就是如此!!!JwGHTML5中文学习网 - HTML5先行者学习网

如此简单,不妨扩展一下

  1. 添加一些自定义参数,谁都喜欢自定义,不是吗?
  2. 支持iScroll, iScroll是一个高性能,资源占用少,无依赖,多平台的javascript滚动插件。
这里我们做了些优化
  1. 图片加载后移除选择器,避免重复判断。
  2. 缓存img元素结合,减少dom元素查询性能损耗
  3. 扩展prototype添加getNode方法,支持分页数据懒加载(由于我们之前缓存了dom元素)

OK!说了这么多,show me the code 吧!JwGHTML5中文学习网 - HTML5先行者学习网

(function () {  var imgList = [],  // 页面所有img元素集合    delay,   // setTimeout 对象    offset,  //偏移量,用于指定图片距离可视区域多少距离,进行加载    time,  // 延迟载入时间    _selector; // 选择器 默认为 .m-lazyload  function _isShow(el) {    var coords = el.getBoundingClientRect();    return ( (coords.top >= 0 && coords.left >= 0 && coords.top) <= (window.innerHeight || document.documentElement.clientHeight) + parseInt(offset));  }  function _loadImage() {    for (var i = imgList.length; i--;) {      var el = imgList[i];      if (_isShow(el)) {        el.src = el.getAttribute('data-src');        el.className = el.className.replace(new RegExp("(//s|^)" + _selector.substring(1, _selector.length) + "(//s|$)"), " ");        imgList.splice(i, 1);      }    }  }  function _delay() {    clearTimeout(delay);    delay = setTimeout(function () {      _loadImage();    }, time);  }  function ImageLazyload(selector, options) {    var defaults = options || {};    offset = defaults.offset || 0;    time = defaults.time || 250;    _selector = selector || '.m-lazyload';    this.getNode();    _delay();//避免首次加载未触发touch事件,主动触发一次加载函数    if (defaults.iScroll) {      defaults.iScroll.on('scroll', _delay);      defaults.iScroll.on('scrollEnd', _delay);    } else {      window.addEventListener('scroll', _delay, false);    }  }  ImageLazyload.prototype.getNode = function () {    imgList = [];    var nodes = document.querySelectorAll(_selector);    for (var i = 0, l = nodes.length; i < l; i++) {      imgList.push(nodes[i]);    }  };})();
 

来源: 实现一个图片懒加载插件有多难? – 前端有多难? – SegmentFaultJwGHTML5中文学习网 - HTML5先行者学习网

(责任编辑:)
推荐书籍
推荐资讯
关于HTML5先行者 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助