资讯专栏INFORMATION COLUMN

原生JS实现图片的懒加载

boredream / 2318人阅读

摘要:方法返回元素的大小及其相对于视口的位置。对象包含了一组用于描述边框的只读属性和,单位为像素。这样就实现了图片的懒加载的简单实现,当然还可以对进行优化等操作,这里不做过多阐述了。演示地址图片的懒加载

思路

首先,什么是懒加载,从字面意思就可以简单的理解为不到用时就不去加载,对于页面中的元素,我们可以这样理解:只有当滚动页面内容使得本元素进入到浏览器视窗时(或者稍微提前,需给定提前量),我们才开始加载图片;

那么我们知道,当不给img元素的src属性赋值时,不会发出请求【不能使src="",这样即使只给src赋了空值也会发出请求】,而一旦给src属性赋予资源地址值,那么该请求发出,使得图片显示;所以这里我们利用这一点控制img元素的加载时机。
在开始的时候将资源url放置在自定义属性data-src当中,然后在需要加载的时候获取该属性并赋值给元素的src属性

难点 视窗内元素判断

从上面的分析可以看出来,主要要解决的问题就是怎么检测到元素是否在视窗当中,这里我们要借助于dom操作api当中的el.getBoundingClientRect()来获取其位置,并判断是否在视窗内,这里简单描述。

Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。返回值是一个 DOMRect 对象,这个对象是由该元素的 getClientRects() 方法返回的一组矩形的集合, 即:是与该元素相关的CSS 边框集合 。DOMRect 对象包含了一组用于描述边框的只读属性——left、top、right和bottom,单位为像素。除了 width 和 height 外的属性都是相对于视口的左上角位置而言的。

因此我们可以使用以下逻辑判断元素是否进入视窗:

        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是为了让懒加载稍稍提前,使用户体验更好;

添加scroll事件监听

那么什么时候去检测元素是否在视窗内,并判断是否加载呢,这里由于页面的滚动会使得元素相对于视窗的位置发生变化,也就是说滚动会改变isInSight的结果,所以这里我们在window上添加scroll事件监听:

        // 当加载完成,检测并加载可视范围内的图片
        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定义如:
加载中
var source = eldom.getAttribute("data-src"); var index = eldom.getAttribute("data-index"); eldom.src = source; console.log("第"+index+"张图片进入视窗,开始加载。。。。") } }

这里就不考虑添加事件的各种兼容性了。

这样就实现了图片的懒加载的简单实现,当然还可以对scroll进行优化等操作,这里不做过多阐述了。

演示地址

(LazyLoadForImg)图片的懒加载

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84705.html

相关文章

  • 图片的预加载和懒加载

    摘要:图片的预加载是提升用户体验而损失性能的一种做法,而懒加载的性能就比较好了,所以将两个结合起来放到程序中是一种不错的选择。 最近在做H5滑页时,遇到一些比较大的场景,动辄二十、三十页,而图片更是可恨的能达到上百个,所以就会导致场景在加载的时候遇到网速比较慢的时候,用户等待的时间特别长,这样的话,就有可能导致一部分的用户没有耐心,而丢失这部分用户,于是就有了这里的图片的预加载和懒加载,记个...

    SwordFly 评论0 收藏0
  • vue项目首页加载速度优化

    摘要:凡是做的项目,特别是移动端的项目,首屏加载速度必定是一个绕不过去的话题。大家知道这些依赖库的文件都会被一起打包到那个文件里面,如果这些你的第三方依赖库很多,很大的话,那就会导致这个文件很大,那首屏加载的速度肯定会被拖慢。 凡是做SPA的项目,特别是移动端的SAP项目,首屏加载速度必定是一个绕不过去的话题。接下来我就我们项目里的一些实践来做一下总结。希望抛砖引玉,如果各位有更好的方案,不...

    rickchen 评论0 收藏0
  • 小程序之图片瀑布流(最全实现方式,额外加送懒加载

    摘要:完整代码请戳我们回到小程序,此时接口返回的数据如下可以看到每个图片都有高度了,接下来我们实现瀑布流布局,等下,我们搞下瀑布流布局的懒加载,关于小程序的懒加载,猛戳了解更多。 效果图 来来来,看啊看,外面的世界多好看, showImg(https://segmentfault.com/img/remote/1460000014887454?w=371&h=580); 效果图展示的是瀑布流...

    rubyshen 评论0 收藏0

发表评论

0条评论

boredream

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<