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

1.有什么应用

  • 懒加载
  • 列表的无限滚动
  • 计算广告元素的曝光情况

2.方法1-----使用offsetTop、scrollTop

offsetTop、scrollTop属于三大家族的内容,详情见https://blog.csdn.net/fageaaa/article/details/145728760

思路:元素的offsetTop-页面的scrollTop<=页面的高度

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
    <style>
      .area1,
      .area3 {
        width: 100%;
        height: 1200px;
        background-color: aqua;
      }
      .box {
        width: 100%;
        height: 100px;
        background-color: red;
      }
    </style>
  </head>
  <body>
    <div class="area1"></div>
    <div class="area2 box"></div>
    <div class="area3"></div>
    <script>
      function isInViewPortOfOne(el) {
        // 下面是浏览器视口的高度的兼容性写法
        const viewPortHeight =
          window.innerHeight ||
          document.documentElement.clientHeight ||
          document.body.clientHeight;
        const offsetTop = el.offsetTop;
        const scrollTop = document.documentElement.scrollTop;
        const top = offsetTop - scrollTop;
        //注意这里只是个简略方式,没考虑el的边框
        return top <= viewPortHeight && top + el.clientHeight >= 0;
      }

      let box= document.querySelector(".box");
      window.addEventListener("scroll", function () {
        if (isInViewPortOfOne(box)) {
          console.log("box元素在可视区域内");
        } else {
          console.log("box元素不在可视区域内");
        }
      });
    </script>
  </body>
</html>

3.方法2-----getBoundingClientRect

getBoundingClientRect函数返回值是一个 DOMRect对象,拥有left, top, right, bottom, x, y, width, 和 height属性。详情见https://blog.csdn.net/fageaaa/article/details/145728760
思路:top大于等于0;left大于等于0;right小于等于viewWidthbottom小于等于viewHeight

function isInViewPort(element) {
    const viewWidth = window.innerWidth || document.documentElement.clientWidth;
    const viewHeight = window.innerHeight || document.documentElement.clientHeight;
    const {
        top,
        right,
        bottom,
        left,
    } = element.getBoundingClientRect();
    return (
        top >= 0 &&
        left >= 0 &&
        right <= viewWidth &&
        bottom <= viewHeight
    );
}

4.方法3-----Intersection Observer

前面两种方式需要一直监听,就算用了防抖节流也要一直监听(只不过性能会好一点)。所以Intersection Observer这个方法性能上会更好!!!

浏览器提供了一种异步观察目标元素与祖先元素(或顶级文档的视口)交叉状态变化的方法。IntersectionObserver详细用法见https://blog.csdn.net/fageaaa/article/details/145741778

<head>
    <meta charset="UTF-8" />
    <title>Title</title>
    <style>
      .area1,
      .area3 {
        width: 100%;
        height: 1200px;
        background-color: aqua;
      }
      .box {
        width: 100%;
        height: 100px;
        background-color: red;
      }
    </style>
  </head>
  <body>
    <div class="area1"></div>
    <div class="area2 box"></div>
    <div class="area3"></div>
    <script>
      let box = document.querySelector(".box");
      //它提供了一种异步观察目标元素与祖先元素(或顶级文档的视口)交叉状态变化的方法。
      // 这个API的出现主要是为了高效解决在网页开发中需要频繁判断元素是否进入“视口”(viewport)的问题。
      // 相比于传统的依赖scroll事件和getBoundingClientRect方法,Intersection Observer API在性能上有显著的优势
      let intersectionObserver = new IntersectionObserver(function (el) {
        if (el[0].intersectionRatio <= 0) {
          console.log("元素彻底离开可视区");
        } else {
          console.log("元素进入可视区");
          //进入可视区之后,资源已经下载好,就不需要再进行监视了
          intersectionObserver.unobserve(box);
        }
      });
      intersectionObserver.observe(box);
    </script>
  </body>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

太阳与星辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值