判断元素是否在可视区域内

Youky ... 2021-10-11 前端
  • JS
About 1 min

# 判断元素是否在可视区域内

# 常见使用场景

  • 图片懒加载
  • 内容预加载,如列表无限滚动
  • 判断某些内容(如广告栏)的曝光情况

# clientHeight、scrollTop、offsetTop

const dom = document.getElementById("targetImg");
window.addEventListener("scroll", function() {
  // 视口总高度
  const viewHeight = document.documentElement.clientHeight;

  // 滚动条已滚动的高度
  const scrollHeight = document.documentElement.scrollTop;

  // 元素出现的位置的高度
  const offsetHeight = dom.offsetTop;
  if (offsetHeight <= viewHeight + scrollHeight) {
    // ... 加载图片
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# getBoundingClientRect

getBoundingClientRect方法返回一个描述元素的DOMRect对象。

该对象提供了获取元素与当前窗口位置关系的属性:

  • top:最上方距离视口顶部的距离。负数表示在视口之上未显示
  • bottom:最下方距离视口顶部的距离

因此判断图片是否出现的逻辑就是:

  • 0 < top < 视口高度(document.documentElement.clientHeight)
const top = dom.getBoundingClientRect().top;
if (top > 0 && top < document.documentElement.clientHeight) {
  // 图片出现
}
1
2
3
4

若考虑水平方向的滚动,就是通过 left 进行判断

# IntersectionObserver

IntersectionObserver是浏览器提供的内置 API,实现了监听滚动条 scroll 事件、判断是否在视口内、节流三个功能。

const imgs = document.getElementsByTagName("img");

const observer = new IntersectionObserver((elems) => {
  for (let elem of elems) {
    // 处于视口之中
    if (elem.isIntersecting) {
      // 实际加载图片
    }
  }
});
observer.observe(imgs);
1
2
3
4
5
6
7
8
9
10
11
Last update: October 16, 2022 21:28
Contributors: youky7 , Youky