原生JS实现图片的懒加载

思路

首先,什么是懒加载,从字面意思就能够简单的理解为不到用时就不去加载,对于页面中的元素,咱们能够这样理解:只有当滚动页面内容使得本元素进入到浏览器视窗时(或者稍微提早,需给定提早量),咱们才开始加载图片;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 外的属性都是相对于视口的左上角位置而言的。优化

avatar

所以咱们可使用如下逻辑判断元素是否进入视窗: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

添加scroll事件监听

那么何时去检测元素是否在视窗内,并判断是否加载呢,这里因为页面的滚动会使得元素相对于视窗的位置发生变化,也就是说滚动会改变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

演示地址

(LazyLoadForImg)图片的懒加载对象

相关文章
相关标签/搜索