网站首页 » 前端开发 » JavaScript » 按需加载图片(图片懒加载)
上一篇:
下一篇:

按需加载图片(图片懒加载)

前言

按需要加载图片,这是一个非常实用的功能,不仅可以提高网站的性能,还可以为你节省流量。对于用虚拟主机的朋友来说,如果你的网站是一个图片网站或者图片比较多的网站,那么图片懒加载功能真不能少。

原理

实现图片懒加载的原理也非常地简单,默认情况下不给图片 scr 属性赋值。当满足一定的条件时才把图片地址取出来赋值给 src 属性。一般地,这上为了让网站页面有更好的用户体验,我们都会预先给所有的图片都设置一张默认的图片,比如一个像素的图片或者其它任意一张图片(只要你喜欢)。

实践代码

我们还是先来看看这个 Demo:http://yunkus.com/demo/load-images-on-demand/

例子中用了一个谈入的效果(CSS 3),如果你想用更多的效果,你可以下载一下 animate.css 库,尝试不同效果展示。在这里就不作过多的讲解,至于 animate.css 库的用法你可以参考这里:

Animate.css 使用教程(一个强大的 CSS3 动画库)

CSS 样式

 .lazy-img-box {
     margin: 0 auto;
     width: 430px;
     overflow: hidden
 }

 .lazy-img-box li {
     list-style: none;
     float: left;
     width: 400px;
     height: 200px;
     margin-right: 12px;
     margin-bottom: 12px;
 }

 .lazy-img-box li img {
     width: 400px;
     height: 200px;
     display: block;
 }

 .animated {
     -webkit-animation-duration: 1s;
     animation-duration: 1s;
     -webkit-animation-fill-mode: both;
     animation-fill-mode: both;
 }

 @-webkit-keyframes fadeIn {
     from {
         opacity: 0;
     }
     to {
         opacity: 1;
     }
 }

 @keyframes fadeIn {
     from {
         opacity: 0;
     }
     to {
         opacity: 1;
     }
 }

 .fadeIn {
     -webkit-animation-name: fadeIn;
     animation-name: fadeIn;
 }

 HTML 代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>按需加载图片(图片懒加载)-云库网</title>
    <meta name="description" content="按需加载图片不仅提高网站性能,还可以为你省了不少流量!" />
    <meta name="keywords" content="JavaScript教程,按需加载图片,图片懒加载" />
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <ul class="lazy-img-box">
        <li><img _src="http://yunkus.com/demo/lib/images/demo-1.jpg" src="./images/loading.gif" alt=""></li>
        <li><img _src="http://yunkus.com/demo/lib/images/demo-2.jpg" src="./images/loading.gif" alt=""></li>
        <li><img _src="http://yunkus.com/demo/lib/images/demo-3.jpg" src="./images/loading.gif" alt=""></li>
        <li><img _src="http://yunkus.com/demo/lib/images/demo-4.jpg" src="./images/loading.gif" alt=""></li>
        <li><img _src="http://yunkus.com/demo/lib/images/demo-5.jpg" src="./images/loading.gif" alt=""></li>
        <li><img _src="http://yunkus.com/demo/lib/images/demo-6.jpg" src="./images/loading.gif" alt=""></li>
        <li><img _src="http://yunkus.com/demo/lib/images/demo-7.jpg" src="./images/loading.gif" alt=""></li>
        <li><img _src="http://yunkus.com/demo/lib/images/demo-8.jpg" src="./images/loading.gif" alt=""></li>
        <li><img _src="http://yunkus.com/demo/lib/images/demo-9.jpg" src="./images/loading.gif" alt=""></li>
        <li><img _src="http://yunkus.com/demo/lib/images/demo-1.jpg" src="./images/loading.gif" alt=""></li>
        <li><img _src="http://yunkus.com/demo/lib/images/demo-2.jpg" src="./images/loading.gif" alt=""></li>
        <li><img _src="http://yunkus.com/demo/lib/images/demo-3.jpg" src="./images/loading.gif" alt=""></li>
        <li><img _src="http://yunkus.com/demo/lib/images/demo-4.jpg" src="./images/loading.gif" alt=""></li>
        <li><img _src="http://yunkus.com/demo/lib/images/demo-5.jpg" src="./images/loading.gif" alt=""></li>
        <li><img _src="http://yunkus.com/demo/lib/images/demo-6.jpg" src="./images/loading.gif" alt=""></li>
        <li><img _src="http://yunkus.com/demo/lib/images/demo-7.jpg" src="./images/loading.gif" alt=""></li>
        <li><img _src="http://yunkus.com/demo/lib/images/demo-8.jpg" src="./images/loading.gif" alt=""></li>
        <li><img _src="http://yunkus.com/demo/lib/images/demo-9.jpg" src="./images/loading.gif" alt=""></li>
    </ul>
    <script src="./index.js"></script>
</body>
</html>

JavaScript 代码

window.onload = function () {
    var lazyImg = document.getElementsByTagName("img");
    var lazyImgLen = lazyImg.length;
    var lazyImgArray = [];
    var winowBroswerHeight = document.documentElement.clientHeight;

    // 初始第一屏图片
    loadImg();

    // 滚动时执行加载图片的方法
    window.onscroll = loadImg;

    // 按需加载图片
    function loadImg() {
        for (var i = 0; i < lazyImgLen; i++) {
            var getTD = getTopDistance(lazyImg[i]);
            var getST = getScrollTop();
            if (!lazyImg[i].loaded && getST < getTD && getTD < (getST + winowBroswerHeight)) {
                lazyImg[i].src = lazyImg[i].getAttribute("_src");
                lazyImg[i].classList.add("animated", "fadeIn");
                lazyImg[i].loaded = true; // 标记为已加载
            }
        }
    }
    // 获取目录对象离 document 文档顶部的距离
    function getTopDistance(obj) {
        var TopDistance = 0;
        while (obj) {
            TopDistance += obj.offsetTop;
            obj = obj.offsetParent;
        }
        return TopDistance;
    }
    // 获取滚动条的滚动距离  
    function getScrollTop() {
        return document.documentElement.scrollTop || document.body.scrollTop;
    }
}

不管滚动条处于什么位置,只要你一刷新,就只会加载处于屏幕里的图片。除此之处不管是屏幕上方的图片,还是屏幕下方的图片只要还没进入屏幕区的都不会被加载。这样的处理方式理论上是比较优的,但是在实践的应用中,却不一定能发展出原有的作用。试想一下,不管你是通过地址直接访问,还是通过搜索引擎进入一个页面,一般情况下都会从页面的顶部内容开始显示,如果你有洁癖想让代码更简单,那么 loadImg() 方法就可以更改成如下代码:

function loadImg() {
    for (var i = 0; i < lazyImgLen; i++) {
        var getTD = getTopDistance(lazyImg[i]);
        var getST = getScrollTop();
        if (!lazyImg[i].loaded && getTD < (getST + winowBroswerHeight)) {
            lazyImg[i].src = lazyImg[i].getAttribute("_src");
            lazyImg[i].classList.add("animated", "fadeIn");
            lazyImg[i].loaded = true; // 标记为已加载
        }
    }
}

其实也没什么变的,只是 if 判断条件少了一个:

getST < getTD

不过也有例外,比如:从列表页中点了评论时,极有可能是跳到详情页后直接跳到评论区,这种情况也很常见,此时就不需要更改代码以达到最优。

这里还有个小问题,关于滚动监听事件的,像上面那样写 window.onscroll = function(){} 一个页面只能用一个,如果有其它地主也用到这个滚动监听事件的话,那么就会只有一个起作用。在这里可以用事件绑定来解决,具体的方法可以查阅这里:常用的 JavaScript 函数封装

  • 微信扫一扫,赏我

  • 支付宝扫一扫,赏我

声明

原创文章,不经本站同意,不得以任何形式转载,如有不便,请多多包涵!

本文永久链接:http://yunkus.com/load-images-on-demand/

发表评论

电子邮件地址不会被公开。 必填项已用*标注

评论 END