图片懒加载Jquery版本

465 阅读4分钟

jquery.lazyload.js简介

  • Lazy Load 是一个用 javaScript 编写的 jQuery 插件,用来实现图片的延迟加载
  • 只有在浏览器可视区域的图片才会被加载,没有滚动到的区域 <img> 标签上会有一个占位图片,真实图片不会被载入。
  • 当页面较长且图片较多时,延迟加载图片可以加快页面加载速度降低服务器负担

使用方法

  • lazyload.js 依赖 jquery
  • 将图片的真实路径放在 <img>data-original 属性
  • <img> 标签添加一个自定义的类名,如 class='lazy',方便 js 调用
 <img class="lazy" data-original="./images/750_04.png">

注意:最好给 <img> 定义 witdh 属性或 height 属性,或者将 img 标签块状化

  • javaScript 调用
 $(document).ready(function () {
   $("img.lazy").lazyload({
     effect:'fadeIn',
     threshold:'350',
     event:'scroll',
     container: $(".wrapper") 
   })
 });

相关属性

  • threshold: 临界点 ,让图片距离屏幕可视区一定像素时提前加载,默认值为 0

  • failure_limit: 当图像不连续时,或布局混乱时使用,默认值为 0

    • 在页面布局时会用到大量的定位样式,如绝对定位,这样呈现的布局效果和 HTML 文档中的 DOM 顺序有很大差异
    • 这样就会存在一种情况,某 <img> 标签已出现在屏幕上,但它却无法显示(因为按顺序加载的话,还没排到它)
    • Lazy Load 在找到第一个未显示的 <img> 标签时,查找已经被终止了,并没有继续往下遍历
    • 当设置了 failure_limit 属性之后,Lazy Load 会查找到对应个数未显示的 <img> 标签处
  • container: 用于设置对某容器中的图片实现效果,默认值 window

    • 这个参数可以让你在拉动某 <div> 的滚动条时依次加载其中的图片
  • event: 触发加载的事件,默认值为 scroll

  • effect: 载入特效,默认值为 show

    • 淡入效果可以设置为 fadeIn
  • skip_invisible: 加载隐藏的图片,默认值为 true

  • placeholder: 默认的占位图片

    • 可以直接把占位图片路径赋给 <img>src属性
  • effectspeed: 设置动画持续时长,单位为 ms ,默认为空

  • appear: 用于在图片加载之前到显示图片之间的处理函数,一般用于展示加载动画

  • load: 用于图片加载完毕之后执行的函数

图片懒加载原理

  1. 设置 <img>src 默认为一张 1px*1pxgif 透明图片(所有默认值都用这一张,那么只会发送一次请求),就是一个转圈圈的背景效果图
 <img data-url="xxx" src="1px.gif" width="180" height="180" />
 img {
   background:url(loading.gif) no-repeat center;
 }
  1. 监听滚动事件,判断图片是否进入可视区,一旦进入视口才进行加载,当滚动加载的时候,就把透明的loading图替换为真正展示的图片
  1. 待图片进入视口后,利用 js 提取 data-url 的真实图片地址赋值给 src 属性,此时才发送请求加载图片,真正实现了按需加载

获取可视区窗口大小

  • 使用 innerWidthinnerHeight 属性获取当前浏览器窗口的大小

  • 某些浏览器没有上述两个属性(如 IE8 及以下),则使用 document.documentElement.clientHeight(dom页面可见高度)document.documentElement.clientWidth(dom页面可见宽度)

    • clientWidth: 元素内容区宽度 + 左右内边距宽度
    • clientHeight: 元素内容区高度 + 上下内边距高度
  • 如果是IE6 中的混杂模式,需要通过 document.body.clientWidthdocument.body. clientHeight 取得相同信息

 let pageWidth,pageHeight
 if (document.compatMode === "CSS1Compat"){
   // 标准模式
   pageWidth = window.innerWidth || document.documentElement.clientWidth; 
   pageHeight = window.innerHeight || document.documentElement.clientHeight;
 }else {
   // 混杂模式
   pageWidth = window.innerWidth || document.body.clientWidth; 
   pageHeight = window.innerHeight || document.body.clientHeight; 
 } 

获取内容滚动的距离

image-20221114162920375.png

  • scrollWidth: 元素的整体宽度,包括由于溢出而无法展示在网页的不可见部分
  • scrollHeight: 元素的整体高度,包括由于溢出而无法展示在网页的不可见部分
  • scrollTop: 元素被卷去的上侧距离
  • scrollLeft: 元素被卷去的左侧距离

判断图片进入可视区域

image-20221114172215449.png

  • 蓝色部分表示可视区域,蓝色区域的高度 innerHeight 和宽度 innerWidth 就是视口的宽高

  • 黑框表示内容大小,scrollTop 内容上边溢出部分,scrollLeft内容左边溢出部分

  • 图片顶部到内容顶部为 offsetTop

  • 图片进入可视区的条件:

    • scrollTop(上边溢出部分) + innerHeight(视口高度) > offsetTop(图片距离顶部的偏移量)
 let imgs = document.getElementsByTagName('img')
 ​
 window.addEventListener('scroll',lazyLoad())
   // 开启节流
 function lazyLoad() {
   let timer = null
   return function () {
     if (!timer) {
       timer = setTimeout(() => {
         let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
           for(let i = 0; i < imgs.length; i++){
             let x = scrollTop + pageHeight - imgs[i].offsetTop 
             // 当内容的偏移量 + 视口高度 > 图片距离内容顶部的偏移量时,说明图片在视口内
             x > 0 && (imgs[i].src = imgs[i].getAttribute('data-url')); 
             //从dataurl中取出真实的图片地址赋值给url
           }  
           timer = null
         }, 200)
       }
     }
   }