jquery图片懒加载

更新日期: 2019-10-08阅读: 2.6k标签: 加载
对于一个有多个图片的网站来说,访问的时候不应该直接加载所有图片,而是应该只将浏览器窗口内的图片进行加载。当滚动的时候,在加载更多的图片,叫做图片的懒加载。我们可以通过给img自定义一个新属性,来存储图片真实的src地址,当需要加载的时候,再将这个真实的地址赋给src,进行图片加载。

整体思路:

1、设置个data-src(自定义一个属性)来存放真实地址
2、当滚动页面时,检查所有的img标签,看是否出现在视野中,如果已经出现在了视野中,那继续再进行判断,看其是否已经被加载过了,如果还没有被加载过,那就进行加载
$(window).on(‘scroll‘,function () {//当页面滚动的时候绑定事件
        $(‘.container img‘).each(function () {//遍历所有的img标签
            if (checkShow($(this)) && !isLoaded($(this)) ){
                // 需要写一个checkShow函数来判断当前img是否已经出现在了视野中
                //还需要写一个isLoaded函数判断当前img是否已经被加载过了
                loadImg($(this));//符合上述条件之后,再写一个加载函数加载当前img
            }
        })
    })
function checkShow($img) { // 传入一个img的jq对象
}
    
function isLoaded ($img) {
}
    
function loadImg ($img) {
}    


判断目标标签是否出现在视野中:

思路为:分析标签出现在页面中的两个临界状态

1、当页面向上滚动,一直滚到首先出现在页面的下边缘的时候,此时有页面向上滚动的距离,加上浏览器自身的高度,就等于目标标签本身在页面中距离页面顶部的距离。

2、页面接着向上滚,当页面出现在了浏览器的上边沿的时候,此时页面向上滚的高度,就等于目标标签本身在页面中距离页面顶部的距离

checkShow函数可以写为:.offset()方法允许我们检索一个元素 (包含其 border 边框,不包括 margin) 相对于文档(document)的当前位置。.offset()返回一个包含top 和 left属性的对象 。表示相对于顶部或者左边的坐标。

function checkShow($img) { // 传入一个img的jq对象
        var scrollTop = $(window).scrollTop();  //即页面向上滚动的距离
        var windowHeight = $(window).height(); // 浏览器自身的高度
        var offsetTop = $img.offset().top;  //目标标签img相对于document顶部的位置

        if (offsetTop < (scrollTop + windowHeight) && offsetTop > scrollTop) { //在2个临界状态之间的就为出现在视野中的
            return true;
        }
        return false;
}


判断目标标签是否已经被加载过:  

function isLoaded ($img) {
   return $img.attr(‘data-src‘) === $img.attr(‘src‘); //如果data-src和src相等那么就是已经加载过了
}


加载目标标签:

function loadImg ($img) {
    $img.attr(‘src‘,$img.attr(‘data-src‘)); // 加载就是把自定义属性中存放的真实的src地址赋给src属性
}

优化代码

1、首先有个明显的问题,第一次进来的时候如果不滚动滚轮的话什么都看不到,想修复这个问题,可以先进行一次页面检查,调用checkShow(),然后页面上在视野中的标签就会被加载,然后再进行监听window的scroll事件。

2、性能的优化,$(window).on(‘scroll‘,function () {}这个事件鼠标滚动的时候触发次数非常多。对性能影响大,优化思路是当鼠标滚轮停止滚动的时候,再去判定是否存在在视野中,而不是滚动过程中一直触发。  

    // 先进行一次检查
    lazyRender();
    //为了不在滚轮滚动过程中就一直判定,设置个setTimeout,等停止滚动后再去判定是否出现在视野中。
    var clock; //这里的clock为timeID,
    $(window).on(‘scroll‘,function () {
//        lazyRender();
        if (clock) { // 如果在300毫秒内进行scroll的话,都会被clearTimeout掉,setTimeout不会执行。
                    //如果有300毫秒外的操作,会得到一个新的timeID即clock,会执行一次setTimeout,然后保存这次setTimeout的ID,
                      //对于300毫秒内的scroll事件,不会生成新的timeID值,所以会一直被clearTimeout掉,不会执行setTimeout.
            clearTimeout(clock);
        }
        clock = setTimeout(function () {
            console.log(‘运行了一次‘);
            lazyRender();
        },300)
    })

最终:

<!DOCTYPE html>
<html lang="en">
<header>
  <meta charset="utf-8">
  <title>图片懒加载</title>
  <script src="./js/jquery.js"></script>
  <style>
    ul,
    li {
      list-style: none;
    }

    .container {
      width: 600px;
      margin: 0 auto;
    }

    .container li {
      float: left;
      margin: 10px 10px;
    }

    .container li img {
      width: 240px;
      height: 180px;
    }

    p {
      float: left;
    }
  </style>
</header>

<body>
  <ul class="container">
    <li><a href="#"><img src="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/1.jpg" /></a></li>
    <li><a href="#"><img src="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/2.jpg" /></a></li>
    <li><a href="#"><img src="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/3.jpg" /></a></li>
    <li><a href="#"><img src="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/4.jpg" /></a></li>
    <li><a href="#"><img src="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/5.jpg" /></a></li>
    <li><a href="#"><img src="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/6.jpg" /></a></li>
    <li><a href="#"><img src="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/7.jpg" /></a></li>
    <li><a href="#"><img src="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/8.jpg" /></a></li>
    <li><a href="#"><img src="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/9.jpg" /></a></li>
    <li><a href="#"><img src="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/10.jpg" /></a></li>
    <li><a href="#"><img src="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/11.jpg" /></a></li>
    <li><a href="#"><img src="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/12.jpg" /></a></li>
    <li><a href="#"><img src="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/13.jpg" /></a></li>
    <li><a href="#"><img src="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/14.jpg" /></a></li>
    <li><a href="#"><img src="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/15.jpg" /></a></li>
    <li><a href="#"><img src="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/16.jpg" /></a></li>
  </ul>
  <script>

    // 先进行一次检查
    lazyRender();

    var clock; //这里的clock为timeID,

    $(window).on(‘scroll‘, function () {//当页面滚动的时候绑定事件      
      if (clock) { // 如果在300毫秒内进行scroll的话,都会被clearTimeout掉,setTimeout不会执行。
        //如果有300毫秒外的操作,会得到一个新的timeID即clock,会执行一次setTimeout,然后保存这次setTimeout的ID,
        //对于300毫秒内的scroll事件,不会生成新的timeID值,所以会一直被clearTimeout掉,不会执行setTimeout.
        clearTimeout(clock);
      }
      clock = setTimeout(function () {
        lazyRender();
      }, 300)
    })
    function lazyRender() {
      $(‘.container img‘).each(function () {//遍历所有的img标签
        if (checkShow($(this)) && !isLoaded($(this))) {
          // 需要写一个checkShow函数来判断当前img是否已经出现在了视野中
          //还需要写一个isLoaded函数判断当前img是否已经被加载过了
          loadImg($(this));//符合上述条件之后,再写一个加载函数加载当前img
        }
      })
    }
    function checkShow($img) { // 传入一个img的jq对象
      var scrollTop = $(window).scrollTop();  //即页面向上滚动的距离
      var windowHeight = $(window).height(); // 浏览器自身的高度
      var offsetTop = $img.offset().top;  //目标标签img相对于document顶部的位置

      if (offsetTop < (scrollTop + windowHeight) && offsetTop > scrollTop) { //在2个临界状态之间的就为出现在视野中的
        return true;
      }
      return false;
    }
    function isLoaded($img) {
      return $img.attr(‘data-src‘) === $img.attr(‘src‘); //如果data-src和src相等那么就是已经加载过了
    }
    function loadImg($img) {
      $img.attr(‘src‘, $img.attr(‘data-src‘)); // 加载就是把自定义属性中存放的真实的src地址赋给src属性
    }
  </script>
</body>

</html>

链接: https://fly63.com/article/detial/5761

懒加载的3种实现方式

优势:性能收益:浏览器加载图片、decode、渲染都需要耗费资源,懒加载能节约性能消耗,缩短onload事件时间。节约带宽:这个不需要解释。

图片懒加载的前世今生

到此,实现图片懒加载主要有两种方法: 监听 scroll 事件,通过 getBoundingClientRect() 计算目标元素与视口的交叉状态;IntersectionObserver 接口。

Vue实现懒加载

什么叫懒加载?就是只有在访问的时候才会进行请求加载,这可以有效提升网站打开的速度,加上这行,就可以做到懒加载↓===括号里的路径改成组件的路径,然后就不需要在上面import了

页面性能优化-原生JS实现图片懒加载

在项目开发中,我们往往会遇到一个页面需要加载很多图片的情况。我们可以一次性加载全部的图片,但是考虑到用户有可能只浏览部分图片。所以我们需要对图片加载进行优化

js实现图片惰性加载

在讲图片的惰性加载前,我们先来聊聊惰性加载。惰性加载又称为延迟加载、懒加载等,还有个好听的英文名字叫做 lazyload。需要注意的是,惰性加载并不只是图片的专利,Javascript 中函数也有惰性加载的概念

小程序如何使用分包加载

在小程序开发的过程中,小程序的体积会随着版本的迭代变的越来越大,这时候我们就希望能够将小程序分成多个包从服务器下载,这样既可以加快首屏的渲染也便于后续按需加载的实现

php的自动加载的使用

在autoload机制引入前,要引用其他文件中的函数和类需使用include/require把文件加载。随着SPL库中的autoload机制以及命名空间的完善,现代化PHP开发鲜少见到以include/require的方式加载类

js判断异步引入的js文件是否加载完毕

在正常的加载过程中,js的加载都是同步的,也就是在加载过程中,浏览器会阻塞接下来的内容的加载。这时候我们就要用到动态加载,动态加载是异步的,如果我们在后边要用到这个动态加载的js文件里的东西

Flutter异步加载:Future,async/await

Future对象表示异步操作的结果,我们通常通过then()来处理返回的结果;async用于标明函数是一个异步函数,其返回值类型是Future对象;await用来等待耗时操作的返回结果,这个操作会阻塞到后面的代码

简单高效实现一个按需加载图片的逻辑

需求:根据页面滚动,当图片进入视野,就开始加载,否则不加载任何图片。页面加载完成时先调用一下,首屏内的图片。代码简单,却很通用,很实用。方便扩展

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!