js实现一个图片懒加载插件

懒加载的意义及实现方式有:

意义: 懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数。

实现方式:

  1. 第一种是纯粹的延迟加载,使用setTimeOut或setInterval进行加载延迟.

  2. 第二种是条件加载,符合某些条件,或触发了某些事件才开始异步下载。

  3. 第三种是可视区加载,即仅加载用户可以看到的区域,这个主要由监控滚动条来实现,一般会在距用户看到某图片前一定距离遍开始加载,这样能保证用户拉下时正好能看到图片。

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

这里需要注意的是: img在初始化的时候不要设置src属性,因为即使设置 src=’’ 浏览器也会尝试加载图片。

一个简单的图片懒加载共涉及两个方面,

1. HTML 约定

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

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

2. JavaScript 实现

动态加载总共分为以下几个步骤,这里每个步骤都将被拆分为独立的函数

  1. 添加页面滚动监听事件

  •       
          
    window.addEventListener( 'scroll', _delay, false);
    function _delay() {
    clearTimeout(delay);
    delay = setTimeout( function () {
    _loadImage();
    }, time);
    }
  • 当触发监听事件时会执行 _loadImage 函数,该函数负责加载图片

    1.         
              
      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函数,但是我们得知道哪些图片需要被加载,这里的判断依据是什么呢?

    依据就是判断该图片是否在当前窗口的可视区域内,在这里我们封装一个_isShow函数来实现

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

    自此一个图片加载的闭环就形成了

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


    太简单了?

    事实就是如此!!!

    如此简单,不妨扩展一下


    1. 添加一些自定义参数,谁都喜欢自定义,不是吗?
    2. 支持iScroll, iScroll是一个高性能,资源占用少,无依赖,多平台的javascript滚动插件。

    这里我们做了些优化

    1. 图片加载后移除选择器,避免重复判断。
    2. 缓存img元素结合,减少dom元素查询性能损耗
    3. 扩展prototype添加getNode方法,支持分页数据懒加载(由于我们之前缓存了dom元素)

    OK!说了这么多,show me the code 吧!

           
           
    ( 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|$)"), " ");el
    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]);
    }
    };
    })();

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值