Skip to content
On this page

1. 实现拆分

  1. 选中内容
  2. 复制

2. 选中内容

2.1 dom位置计算1

图片

  • 通过window.onload事件初始化计算
  • 通过window.scroll事件监听触发, 实现动态计算
  • 视图高度和滚动顶部距离与图片的顶部距离作对比, 得出是否出现在当前视图中
js
视图scrollTop + 视图clientHeight  > 图片offsetTop

2.2 getBoundingClientRect API获取

图片

  • 通过window.scroll事件监听触发, 实现动态计算, 并且 节流 处理, 减少判断次数
  • ele.getBoundingClientRect() 可获取元素大小及相对视图的位置
  • getBoundingClientRect().top: 相对视图窗口的顶部距离
  • clientHeight: 当前视口的高度

当网页往下滚动时, 图片距离视窗口的顶部距离就越来越小, 即getBoundingClientRect的top变小, 当顶部距离和视图窗口的高度一致时, top === clientHeight. 图片即将进入视图窗口, 紧贴在视图窗口的下方. 所以得出视图内公式

js
img.getBoundingClientRect().top < document.documentElement.clientHeight

无需关注图片滚动到视图窗口的上方, 目的是做懒加载, 已经加载过了.

IE浏览器兼容

2.3 IntersectionObserver API获取

前面方法依赖两步

  1. window.scroll监听, 节流
  2. 位置计算

浏览器出了一个IntersectionObserver事件, 用于监听元素是否到达可视窗口

js
const observer = new IntersectionObserver((changes) => {
  // changes: 监听的所有目标元素集合
  changes.forEach((change) => {
    // intersectionRatio
    if (change.isIntersecting) { // 是否在可视窗口内
      // 控制图片加载
      const img = change.target; // 目标元素
      img.src = img.dataset.src;
      observer.unobserve(img);
    }
  });
});

observer.observe(img); // 监听元素

IE浏览器不兼容

3.3 LazyLoading 属性

html
<img src="demo.jpg" loading="lazy" />

一行html即可, 但兼容性差

3. 复制

3.1 DataSet Api

在html中设置图片的data-src属性

html
<img data-src="xx.png">

在需要加载时, 将其设置 img.src = img.dataset.src

总结

参考资料