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

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

实现方式:

  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);            

function () {            

                  _loadImage();            

                }, time);            

              }


  • 当触发监听事件时会执行 _loadImage 函数,该函数负责加载图片


function _loadImage() {                

for (                  var

var

if

'data-src');                

new                   RegExp(                  "(\\s|^)" + _selector.substring(                  1, _selector.length) +                   "(\\s|$)"),                   " ");                

1);                

                      }                

                    }                

                  }

虽然执行了_loadImage函数,但是我们得知道哪些图片需要被加载,这里的判断依据是什么呢?

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


function _isShow(el) {            

var

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元素集合

// setTimeout 对象

//偏移量,用于指定图片距离可视区域多少距离,进行加载

// 延迟载入时间

// 选择器 默认为 .m-lazyload



function _isShow(el) {              

var

return ( (coords.top >=                 0 && coords.left >=                 0 && coords.top) <= (                window.innerHeight ||                 document.documentElement.clientHeight) +                 parseInt(offset));              

                  }              



function _loadImage() {              

for (                var

var

if

'data-src');              

new                 RegExp(                "(\\s|^)" + _selector.substring(                1, _selector.length) +                 "(\\s|$)"),                 " ");el              

1);              

                      }              

                    }              

                  }              



function _delay() {              

                    clearTimeout(delay);              

function () {              

                      _loadImage();              

                    }, time);              

                  }              



function ImageLazyload(selector, options) {              

var

0;              

250;              

'.m-lazyload';              

this.getNode();              

//避免首次加载未触发touch事件,主动触发一次加载函数

if

'scroll', _delay);              

'scrollEnd', _delay);              

else

window.addEventListener(                'scroll', _delay,                 false);              

                    }              

                  }              

function () {              

                    imgList = [];              

var nodes =                 document.querySelectorAll(_selector);              

for (                var i =                 0, l = nodes.length; i < l; i++) {              

                      imgList.push(nodes[i]);              

                    }              

                  };              

                })();