首先,什么是懒加载,从字面意思就能够简单的理解为不到用时就不去加载,对于页面中的元素,咱们能够这样理解:只有当滚动页面内容使得本元素进入到浏览器视窗时(或者稍微提早,需给定提早量),咱们才开始加载图片;api
那么咱们知道,当不给img元素的src属性赋值时,不会发出请求【不能使src="",这样即便只给src赋了空值也会发出请求】,而一旦给src属性赋予资源地址值,那么该请求发出,使得图片显示;因此这里咱们利用这一点控制img元素的加载时机。
在开始的时候将资源url放置在自定义属性data-src当中,而后在须要加载的时候获取该属性并赋值给元素的src属性浏览器
从上面的分析能够看出来,主要要解决的问题就是怎么检测到元素是否在视窗当中,这里咱们要借助于dom操做api当中的el.getBoundingClientRect()来获取其位置,并判断是否在视窗内,这里简单描述。dom
Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。返回值是一个 DOMRect 对象,这个对象是由该元素的 getClientRects() 方法返回的一组矩形的集合, 即:是与该元素相关的CSS 边框集合 。DOMRect 对象包含了一组用于描述边框的只读属性——left、top、right和bottom,单位为像素。除了 width 和 height 外的属性都是相对于视口的左上角位置而言的。优化
所以咱们可使用如下逻辑判断元素是否进入视窗:url
function isInSight(el){ var eldom = typeof el == 'object'?el:document.querySelector(el); var bound = eldom.getBoundingClientRect(); // 这里的bound包含了el距离视窗的距离; // bound.left是元素距离窗口左侧的距离值; // bound.top是袁术距离窗口顶端的距离值; // 以以上两个数值判断元素是否进入视窗; var clientHeigt = window.innerHeight; var clientWidth = window.innerWidth; // return (bound.top>=0&&bound.left>=0)&&(bound.top<=window.innerHeight+20)&&(bound.left<=window.innerWidth+20); return !((bound.top>clientHeigt)||(bound.bottom<0)||(bound.left>clientWidth)||(bound.right<0)) }
其中window.innerHeight和window.innerWidth分别为视窗的高度和宽度,之因此加上20是为了让懒加载稍稍提早,使用户体验更好;spa
那么何时去检测元素是否在视窗内,并判断是否加载呢,这里因为页面的滚动会使得元素相对于视窗的位置发生变化,也就是说滚动会改变isInSight的结果,因此这里咱们在window上添加scroll事件监听:.net
// 当加载完成,检测并加载可视范围内的图片 window.onload= checkAllImgs; // 添加滚动监听,便可视范围变化时检测当前范围内的图片是否能够加载了 window.addEventListener("scroll",function(){ checkAllImgs(); }) // 检测全部图片,并给视窗中的图片的src属性赋值,即开始加载; function checkAllImgs(){ var imgs = document.querySelectorAll("img"); Array.prototype.forEach.call(imgs,function(el){ if(isInSight(el)){ loadImg(el); } }) } // 开始加载指定el的资源 function loadImg(el){ var eldom = typeof el == 'object'?el:document.querySelector(el); if(!eldom.src){ // 懒加载img定义如:<div class="img"><img alt="加载中" data-index=7 data-src="http://az608707.vo.msecnd.net/files/MartapuraMarket_EN-US9502204987_1366x768.jpg"></div> var source = eldom.getAttribute("data-src"); var index = eldom.getAttribute("data-index"); eldom.src = source; console.log("第"+index+"张图片进入视窗,开始加载。。。。") } }
这里就不考虑添加事件的各类兼容性了。prototype
这样就实现了图片的懒加载的简单实现,固然还能够对scroll进行优化等操做,这里不作过多阐述了。code