用IntersectionObserver实现图片懒加载

Posted hans774882968

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用IntersectionObserver实现图片懒加载相关的知识,希望对你有一定的参考价值。

使用IntersectionObserver这个api可以更简便地实现图片的懒加载。它是浏览器原生提供的构造函数,它的用法网上也不少,且不容易踩坑。

值得注意的是,如果图片没加载时默认高度为0,那么这个懒加载效果就会打不少折扣,这个折扣程度和前几张图片的高度有关。比如我本地如果不开console(底部),刚进入页面就会一次性全部加载。开console并拉到占据大部分高度的位置,才能让它刚进入页面时,只加载2张图片。所以我们为.img-area预设了一个min-height。

html+CSS
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>滚动加载更多</title>
  <!--<link rel="stylesheet" type="text/css" href = "./index.css" />-->
  <!--<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>-->
  <!-- <script src="https://cdn.staticfile.org/vue/2.5.2/vue.min.js"></script> -->
  <style>
    body{
      margin: 0;
    }
    .container{
      width: 100%;
    }
    .img-area{
      margin-top: 40px;
      text-align: center;
      min-height: 400px;/* 预设一个高度,使得IntersectionObserver效果不打折扣 */
    }
    .to-top-wrap{
      background-color: skyblue;
      font-size: 26px;
      color: white;
      text-align: center;
      padding: 12px;
      max-width: 69px;/* 字体26px,两行显示时,内容高度是69px,因此设置为和高度一样 */
      cursor: pointer;
      position: fixed;
      bottom: 150px;
      right: 80px;
    }
    .to-top-wrap:hover{
      background-color: deepskyblue;
    }
  </style>
</head>
<body>
<main class="container">
  <section class="img-area">
    <img class="my-photo" class="my-photo" data-src="./imgs/img1.png" />
  </section>
  <section class="img-area">
    <img class="my-photo" data-src="./imgs/img2.png" />
  </section>
  <section class="img-area">
    <img class="my-photo" data-src="./imgs/img3.png" />
  </section>
  <section class="img-area">
    <img class="my-photo" data-src="./imgs/img4.png" />
  </section>
  <section class="img-area">
    <img class="my-photo" data-src="./imgs/img5.png" />
  </section>
  <section class="img-area">
    <img class="my-photo" data-src="./imgs/img6.png" />
  </section>
  <section class="img-area">
    <img class="my-photo" data-src="./imgs/img7.png" />
  </section>
  <section class="img-area">
    <img class="my-photo" data-src="./imgs/img8.png" />
  </section>
</main>
<div class="to-top-wrap">
  回到顶部
</div>
<script src="./加载更多+回到顶部-observer.js"></script>
</body>
</html>
JS

JS参照网上的demo写就行,不会踩坑。和我之前的实现方案(传送门)的码量相比,少太多了,可惜兼容性差一些。

"use strict";

let io = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (!entry.isIntersecting) return
    const img = entry.target
    img.src = img.dataset.src
    io.unobserve(img)
    console.log(img)
  })
})

let imgs = document.querySelectorAll('.my-photo')
imgs.forEach(img => {
  io.observe(img)
})

let toTop = document.querySelector('.to-top-wrap')
toTop.addEventListener('click', () => {
  document.documentElement.scrollTop = 0
})

参考:https://www.ruanyifeng.com/blog/2016/11/intersectionobserver_api.html

以上是关于用IntersectionObserver实现图片懒加载的主要内容,如果未能解决你的问题,请参考以下文章

图片懒加载高性能实现(IntersectionObserver方法)

使用IntersectionObserver更高效的监视某个页面元素是否进入了可见窗口

使用IntersectionObserver更高效的监视某个页面元素是否进入了可见窗口

图片懒加载_intersectionObserver

IntersectionObserver 监听元素是不是出现或离开可视区域

IntersectionObserver API 之学习