美文网首页React
原生JS实现图片懒加载

原生JS实现图片懒加载

作者: JacobMa1996 | 来源:发表于2017-05-18 21:42 被阅读2446次

最近接的项目终于接近尾声,这段时间一直没有造轮子,在实现设计图还原的途中,发现还是有一些技术需要掌握,难者不会,会者不难,没有实际操作过的东西在项目中毫无头绪,而懒加载在实际开发中是一个很有效的东西,在页面中我们往往需要放上很多张图,性能是个大问题,一次性加载所有图片一般都会卡很久,因此,在需要预览的时候再加载,是一个很好的解决方案。
参考了https://www.denpe.com/javascript-images-lazyload/
实现懒加载有很多种方法,但基本原理是相同的,就是当图片出现在浏览器可视区域中时,再把图片的url传给它,也可以在这个时候创建图片,而图片被包裹在一个容器中,比如li或div,图片的url放在其容器的自定义属性data-src中;
考虑到模块的独立,这里不用容器,直接使用img

原理图.png

判定其加载条件是,当图片距离页面顶端的距离小于浏览器滚动距离加上可视区域高度,即它出现在可视区域时,就加载它;

  • 获取图片距离页面顶端的高度利用offsetTop计算出其距离offsetParent的高度,再循环叠加,最终获取到其距离页面顶端的高度:
//offsetTop是元素与offsetParent的距离,循环获取直到页面顶部
        function getTop(e) {
            var T = e.offsetTop;
            while(e = e.offsetParent) {
                T += e.offsetParent;
            }
            return T;
        }
  • 可视区域高度为
var H = window.innerHeight;
  • 滚动距离为
var S = document.documentElement.scrollTop || document.body.scrollTop;

然后定义赋值函数

function lazyLoad(imgs) {
            var H = window.innerHeight;
            var S = document.documentElement.scrollTop || document.body.scrollTop;
            for (var i = 0; i < imgs.length; i++) {
                if (H + S > getTop(imgs[i])) {
                    imgs[i].src = imgs[i].getAttribute('data-src');
                }
            }
        }

最后在把页面滚动函数赋值给元素window.onload,在所有元素加载完以后再进行操作,这一步很重要!

window.onload = window.onscroll = function () {
            lazyLoad(imgs);
        }

全部代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>图片懒加载</title>
</head>

<style>
    img {
        display: block;
    }
</style>

<body>
<div>
    <img src="" data-src="images/girl1.jpg" alt="图片">
    <img src="" data-src="images/girl1.jpg" alt="图片">
    <img src="" data-src="images/girl1.jpg" alt="图片">
    <img src="" data-src="images/girl1.jpg" alt="图片">
    <img src="" data-src="images/girl1.jpg" alt="图片">
    <img src="" data-src="images/girl1.jpg" alt="图片">
    <img src="" data-src="images/girl1.jpg" alt="图片">
    <img src="" data-src="images/girl1.jpg" alt="图片">
    <img src="" data-src="images/girl1.jpg" alt="图片">
    <img src="" data-src="images/girl1.jpg" alt="图片">
    <img src="" data-src="images/girl1.jpg" alt="图片">
    <img src="" data-src="images/girl1.jpg" alt="图片">
    <img src="" data-src="images/girl1.jpg" alt="图片">

</div>
</body>
<script type="text/javascript">

        var imgs = document.querySelectorAll('img');

        //offsetTop是元素与offsetParent的距离,循环获取直到页面顶部
        function getTop(e) {
            var T = e.offsetTop;
            while(e = e.offsetParent) {
                T += e.offsetTop;
            }
            return T;
        }

        function lazyLoad(imgs) {
            var H = window.innerHeight;
            var S = document.documentElement.scrollTop || document.body.scrollTop;
            for (var i = 0; i < imgs.length; i++) {
                if (H + S > getTop(imgs[i])) {
                    imgs[i].src = imgs[i].getAttribute('data-src');
                }
            }
        }

        window.onload = window.onscroll = function () {
            lazyLoad(imgs);
        }


//    var imgs = document.body.querySelectorAll('img'),
//        H = window.innerHeight;  //浏览器视窗高度
//    function lazyload() {
//        var S = document.documentElement.scrollTop || document.body.scrollTop;   //滚动条滚过高度
//        [].forEach.call(imgs, function (img) {
//            if (!img.getAttribute('data-src')) {
//                return
//            }  //已经替换过的跳过
//            if (H + S - 200 > getTop(img)) {    //为达到演示效果,这里H+S减去200,延后加载时机
//                img.src = img.getAttribute("data-src");
//                img.removeAttribute("data-src");
//            }
//        });
//        [].every.call(imgs, function (img) {
//            return !img.getAttribute('data-src')
//        }) && (window.removeEventListener("scroll", lazyload, false));   //完成所有替换后注销事件
//
//    }
//
//    window.addEventListener("scroll", lazyload, false);
//    window.addEventListener("load", lazyload, false);
//
//    function getTop(e) {
//        var T = e.offsetTop;
//        while (e = e.offsetParent) {
//            T += e.offsetTop
//        }
//        return T
//    }


</script>
</html>

下面注释的是比较完善的方法,还有其他实现方法。

相关文章

  • 图片懒加载

    前端实现图片懒加载(lazyload)的两种方式 原生JS实现最简单的图片懒加载 30行Javascript代码实...

  • 原生JS实现图片懒加载

    (1) 图片距离文档顶部的高度: img.offsetTop(2) 返回窗口文档显示区的高度: window.in...

  • 原生JS实现图片懒加载

    最近接的项目终于接近尾声,这段时间一直没有造轮子,在实现设计图还原的途中,发现还是有一些技术需要掌握,难者不会,会...

  • 原生 JS 实现图片懒加载

    1、什么是懒加载? 懒加载就是延迟加载的意思,比如我们加载一个页面,这个页面很长很长,长到我们的浏览器可视区域装不...

  • 原生js实现图片懒加载

    用多了懒加载插件,尝试一下自己撸一个,顺便了解其中原理和实现方法吧。 什么是懒加载 懒加载其实就是延迟加载,是一种...

  • 原生JS实现图片懒加载(lazyload)

    前言 图片懒加载也是比较常见的一种性能优化的方法,最近在用vue做一个新闻列表的客户端时也用到了,这里就简单介绍下...

  • 原生js 图片懒加载

  • 原生js 图片懒加载

    1、使用方法 1、引入下面js2、在img添加 class="lazyloadimg" 类名,src 里面是默认图...

  • JS 原生图片懒加载

  • js实现图片懒加载

    原生js实现图片懒加载需要的条件1、scroll事件2、元素是否处于可视区域 当scroll事件触发的时候,根据计...

网友评论

  • Heartwithmymove:有个问题,就是在鼠标滚轮滚动时,滚动条会的长度会持续变化,怎么解决呢?
    JacobMa1996:滚动条浏览器会计算的,不需要关系
  • 竹林居:请问一下 文中的 window.innerHeight 跟 document.documentElement.clientHeight有什么区别
    JacobMa1996:前者针对非IE,后者针对IE早期版本,不同的API而已。
  • 70f9d9990d28:function getTop(e) {
    var T = e.offsetTop;
    while(e = e.offsetParent) {
    T += e.offsetParent;
    }
    return T;
    }
    这里有个小错误,应该是T += e.offsetTop 而不是T += e.offsetParent
    JacobMa1996:是的,谢谢提出
  • 楼心漫:getBoundingClientRect()可以直接获取元素到顶部的距离哦,可以看下这个方法
    Heartwithmymove:对滴!这个方法超好用的
    JacobMa1996:好的谢谢

本文标题:原生JS实现图片懒加载

本文链接:https://www.haomeiwen.com/subject/sgkexxtx.html