用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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值