使用img标签加载图片,在网页上显示图片,这里就简单的设置一下样式了,主要目的是展示图片的不同加载方式。

1.普通实现方式

普通的实现方式就是不做任何处理,需要使用到图片时就去加载图片,这些图片一般存储在图片服务器上;因此这种方式会在图片较多时,需要加载很长时间,用户体验感很差。(本例中使用本地图片,且数量较少,所以差别不大;理解其实现差异即可)
html文件

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="referrer" content="no-referrer" />
    <title>JQ图片加载</title>
    <!-- 引用JQ -->
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
  </head>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    .container {
      margin: 70px auto 0;
      width: 90%;
      height: 600px;
      border: 1px solid #000;
    }

    .container img {
      width: 100%;
      height: 100%;
    }
    .p-btn {
      text-align: center;
    }

    .p-btn a {
      /* a 标签是内联标签,没办法设置高度,所以要先转换为内联块。 */
      display: inline-block;
      text-decoration: none;
      line-height: 30px;
      width: 60px;
      height: 30px;
      border: 1px solid #333;
      margin: 20px;
    }
  </style>
  <body>
    <!-- 相册 -->
    <div class="container">
      <!-- 图片 -->
      <img
        src="img/1.jpeg"
        alt="pic"
        id="img"
      />
    </div>
    <!-- 按钮 -->
    <p class="p-btn">
      <!-- 上一页按钮 -->
      <!-- 
            <a href="javascript:;">  执行一段空白的javascript语句,返回空或者false值,从而防止链接跳转
        -->
      <a href="javascript:;" class="btn" data-btn="prev"> 上一页 </a>
      <!-- 下一页按钮 -->
      <a href="javascript:;" class="btn" data-btn="next"> 下一页 </a>
    </p>
  </body>
</html>

js文件

    // 图片资源数组
    var imgs = [
      "img/1.jpeg",
      "img/2.jpeg",
      "img/3.jpeg",
      "img/4.jpeg",
      "img/5.jpeg",
    ];
  
    var index = 0; //表示当前是第几张图片 imgs 的索引值
    var len = imgs.length; //获取图片资源数组长度,也就是有几张图片
  
    //   按钮点击事件
    $(".btn").on("click", function() {
      //   data("btn") 代表获取 src的值
      // 如果值为 prev 也就是上一页的时候
      console.log(this);
      // this表示被点击的a标签,因为是该a标签调用了click函数
      if ($(this).data("btn") === "prev") {
        index--; //索引减一
        //   如果索引值小于 0 则应该赋值为 0 ,因为索引值没有负数
        if (index < 0) {
          index = 0;
        }
        //   下一页
      } else {
        index++; //索引加一
        //   因为索引值最大为 imgs.length-1,所以和它进行比较
        if (index > len - 1) {
          index = len - 1;
        }
      }
      // 为图片的src设置相应的图片地址值
      $("#img").attr("src", imgs[index]);
    });

2.预加载的实现方式

预加载是一个性能优化技术,我们可以使用该技术来预先告知浏览器某些资源可能在将来会被使用到。预加载简单来说就是将所有所需的资源提前请求加载到本地,这样后面在需要用到时就直接从缓存取资源。

为什么使用预加载
在网页全部加载之前,对一些主要内容进行加载,以提供给用户更好的体验,减少等待的时间。否则,如果一个页面的内容过于庞大,没有使用预加载技术的页面就会长时间的展现为一片空白或没有变化,直到所有内容加载完毕。

使用预加载解决之前的问题
未做任何处理时,当我们点击下一页时,可能图片还没有加载完成,这时会出现一种假死的状态,页面在加载图片资源而没有任何反应,用户体验感不好。

使用预加载处理:让图片相册快速无缝隙的展示,在等待过程中显示正在加载的文字或者图片,等所有资源加载完成后再一次性展示。

html文件

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- 访问网上图片时, 为了避免访问图片出现403 -->
    <meta name="referrer" content="no-referrer" />
    <title>JQ图片预加载</title>
    <!-- 引用JQ -->
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
  </head>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    html,
    body {
      height: 100%;
    }
    .container {
      margin: 70px auto 0;
      width: 90%;
      height: 600px;
      border: 1px solid #000;
    }

    .container img {
      width: 100%;
      height: 100%;
    }
    .p-btn {
      text-align: center;
    }

    .p-btn a {
      /* a 标签是内联标签,没办法设置高度,所以要先转换为内联块。 */
      display: inline-block;
      text-decoration: none;
      line-height: 30px;
      width: 60px;
      height: 30px;
      border: 1px solid #333;
      margin: 20px;
    }
    .loading-box {
      /* 固定,不让随着滚动条变化而发生变化 */
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      /* 直接写 height:100%; 其实是没有作用的,因为这里的百分比继承与他的父类,没有给父类设置高度,所以要在前面为html,body设置高度 */
      background: #eee;
      text-align: center;
      font-size: 30px;
    }

    .progress {
      margin-top: 300px;
    }
  </style>
  <body>
    <!-- 相册 -->
    <div class="container">
      <!-- 图片 -->
      <img
        src="img/1.jpeg"
        alt="pic"
        id="img"
      />
    </div>
    <!-- 按钮 -->
    <p class="p-btn">
      <!-- 上一页按钮 -->
      <!-- 
            <a href="javascript:;">  执行一段空白的javascript语句,返回空或者false值,从而防止链接跳转
        -->
      <a href="javascript:;" class="btn" data-btn="prev"> 上一页 </a>
      <!-- 下一页按钮 -->
      <a href="javascript:;" class="btn" data-btn="next"> 下一页 </a>
    </p>
    <div class="loading-box">
      <!-- 
            默认情况下,加载进度是零,占满所有可视区域,并且不应该随着滚动条变化而发生变化 
      -->
      <!-- 进度条 -->
      <p class="progress">
        0%
      </p>
    </div>
  </body>

相比于上面没做任何处理,此处添加一个进度条,用来显示图片资源的加载情况。

js文件

    // 图片资源数组
    var imgs = [
      "img/1.jpeg",
      "img/2.jpeg",
      "img/3.jpeg",
      "img/4.jpeg",
      "img/5.jpeg",
    ];

    var index = 0;
    var len = imgs.length;

    // 计数器
    var count = 0; //初始化已加载的图片为 0
    var $progress = $(".progress");

    $.each(imgs, function(i, src) {
      // i 是索引
      // 每遍历一个元素就通过new 来实例化一个img对象
      var imgObj = new Image();

      $(imgObj).on("load error", function() {
        //  $progress.html() 是修改  <p class="progress"></p> 标签的百分比内容
        // ((count + 1) / len) * 100)+ "%" 是用已加载的图片数除以总图片数乘以 100,加上百分号来代表加载进度
        // Math.round() 是取整数
        $progress.html(Math.round(((count + 1) / len) * 100) + "%");

        // 当加载图片数量大于或等于len-1时,隐藏掉loading页
        if (count >= len - 1) {
          $(".loading-box").hide();
        }

        count++;
      });
      // 加载完成后为图片的 src 赋值
      imgObj.src = src;
    });

    $(".btn").on("click", function() {
      if ($(this).data("btn") === "prev") {
        index--;
        if (index < 0) {
          index = 0;
        }
      } else {
        index++;
        if (index > len - 1) {
          index = len - 1;
        }
      }
      $("#img").attr("src", imgs[index]);
    });

使用 each() 方法来遍历我们的图片资源,遍历到该元素时执行 var imgObj = new Image(); 来实例化一个 img 对象,img 对象自带有两个事件,一个是当我们的图片被正常加载完成后会触发一个 load 事件,另一个则是图片未能被正常加载完成后触发的 error 事件。

使用 $(imgObj).on(“load”,function(){}) 为当前 img 对象绑定一个 load 事件,当前的图片资源加载完成后,我们需要更改进度,在此之前需要一个计数器,来记一下我们现在加载了几张图片,也就是 var count = 0;。当前图片加载完成后,执行 count++ 操作,这样就能知道现在加载到第几张图片。

Math.round() 函数是返回一个四舍五入后最接近的整数,在这里是为了避免百分比出现小数。

注意点:
这里的 load() 方法指的是图片能够加载完成所执行的函数,如果出现其中一个图片加载失败怎么办呢?那么 loading 页面永远不会消失,用户也永远见不到后面的相册了。为了保证程序继续执行下去,在加载失败时也要执行相同的方法。这就是为什么所给的代码里有个 error 的原因了。

3.懒加载的实现方式

懒加载也叫延迟加载,指的是在长网页中延迟加载图像,是一种很好优化网页性能的方式。用户滚动到它们之前,可视区域外的图像不会加载。这与图像预加载相反,在长网页上使用延迟加载将使网页加载更快。在某些情况下,它还可以帮助减少服务器负载。常适用图片很多,页面很长的网站场景中。

为什么使用懒加载

1.提升用户体验
不妨设想下,用户打开像淘宝这样的长页面的时候,如果页面上所有的图片都使用预加载,因为图片数目较大而导致等待时间很长,用户难免会心生抱怨,这就严重影响用户体验。

2.减少无效资源的加载
如果我们只加载自己所看到的部分,这样能明显减少了服务器的压力,也能够减小浏览器的负担。

3.防止并发加载的资源过多会阻塞 js 的加载
过多的资源加载会阻塞 JS 的加载以至于影响网站正常使用。

懒加载的基本原理
标签有一个属性是 src,用来表示图像的 url,当这个属性的值不为空时,浏览器就会根据这个值发送请求。如果没有 src 属性,就不会发送请求。所以我们的思路就是:我们先不给 设置 src,把图片真正的 url 放在另一个属性 src 中,在需要的时候也就是图片进入可视区域的之前,将 url 取出放到 src 中。

html文件

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JQ图片懒加载</title>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    <link rel="stylesheet" href="./index.css" />
  </head>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    .box {
      /* flex布局让 .img-item 向下排列  */
      display: flex;
      margin: 0 auto; /* 居中 */
      flex-direction: column;
      width: 500px;
    }
    .img-item {
      border: 1px solid #000;
      height: 400px;
      width: 400px;
      margin: 20px;
    }
  </style>
  <body>
    <div class="box">
      <img
        src="img/1.jpeg"
        class="img-item"
        alt="loading"
      />
      <img
        src="img/2.jpeg"
        class="img-item"
        alt="loading"
      />
      <img
        src="img/3.jpeg"
        class="img-item"
        alt="loading"
      />
      <img
        src="img/4.jpeg"
        class="img-item"
        alt="loading"
      />
      <img
        src="img/5.jpeg"
        class="img-item"
        alt="loading"
      />
      <img
        src="img/1.jpeg"
        class="img-item"
        alt="loading"
      />
      <img
        src="img/2.jpeg"
        class="img-item"
        alt="loading"
      />
      <img
        src="img/3.jpeg"
        class="img-item"
        alt="loading"
      />
      <img
        src="img/4.jpeg"
        class="img-item"
        alt="loading"
      />
      <img
        src="img/5.jpeg"
        class="img-item"
        alt="loading"
      />
    </div>
  </body>
</html>

注意:为了展示效果,一开始会为图片的 src 赋值。
预览效果:
在这里插入图片描述

进一步修改:原理:如果图片元素距离文档顶部的高度小于浏览器的滚动高度加浏览器的可视高度,则需要加载。

第一步:将每个 src 属性修改为 data-src,举其中一个例子:

<img
  data-src="img/1.jpeg"
  class="img-item"
  alt="loading"
/>

预览效果:
在这里插入图片描述
第二步,添加js代码

    // 获取img
    var imgs = $('img');
    // 懒加载方法
    var lazyload = function () {
        // 获取浏览器滚动高度
        var scrollTop = $(document).scrollTop();
        // 获取浏览器可视高度
        var winTop = $(window).height();

        $('img').each(function (i, el) {
            // 如果元素距离文档顶部的高度小于浏览器的滚动高度加浏览器的可视高度,则需要加载
            // $(this).offset().top:图片元素距离文档顶部的高度
            if ($(this).offset().top < scrollTop + winTop) {
            // 为需要加载的图片的 src 属性赋值
                $(this).attr('src', $(this).data('src'));
            }
        });
    };

    // 节流函数
    function throttle(method, delay) {
        var timer = null;
        return function () {
            clearTimeout(timer); // 执行之前清除上一个
            timer = setTimeout(function () {
                method(); // 执行懒加载方法
            }, delay);
        };
    }
    // 打开网页先加载可视区域的图片
    window.onload = lazyload();
    // window.onscroll 是鼠标滚动事件
    window.onscroll = throttle(lazyload, 200);

注意:这里的 throttle 函数是一个节流函数,也就是不要让我们的懒加载方法执行得太频繁,减少一些过快的调用来节流。

预览效果:
在这里插入图片描述
至此该demo也就基本完成了,预加载和懒加载的区别在于:两种技术的区别,一个是提前加载,一个是迟缓甚至不加载。

demo源码下载地址:demo源码下载

更多推荐