【JS场景题】判断一个元素是否在可视区域内有哪些方法?

发布于:2024-07-05 ⋅ 阅读:(19) ⋅ 点赞:(0)

方法一、通过元素的位置信息和滚动条滚动的高度来判断

前置知识

  • clientWidth: 元素的内容区域宽度加上左右内边距宽度。
  • offsetTop: 元素的上外边框至包含元素的上内边框之间的像素距离。
  • document.documentElement.clientHeight: 获取视口高度(不包含滚动条的隐藏高度)。
  • document.documentElement.scrollHeight:获取浏览器窗口的总高度(包含滚动条的隐藏高度)。
  • document.documentElement.scrollTop: 获取滚动条滚动的高度

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .div {
            height: 2000px;
        }
        p {
            height: 200px;
            color: white;
            background-color: blueviolet;
        }
    </style>
</head>
<body>
    <!-- 1. 通过元素的位置信息和滚动条滚动的高度来判断 -->
     <div class="div"></div>
     <p>我出现啦</p>
     <script>
        function isContain(dom) {
            // 获取可视窗口的高度- 兼容写法
            const screenHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
            // 获取滚动条滚动的高度
            const scrollTop = document.documentElement.scrollTop;
            // 获取元素偏移的高度,就是距离可视窗口的偏移量
            const offsetTop = dom.offsetTop;
            return offsetTop - scrollTop <= screenHeight;
        }
        const p = document.querySelector('p')
        window.onscroll = () => {
            if (isContain(p)) {
                document.body.style.backgroundColor = 'blue'
            } else {
                document.body.style.backgroundColor = 'skyblue'
            }
        }
     </script>
</body>
</html>

方法二、通过getBoundingClientRect方法来获取元素的位置信息,然后加以判断

前置知识

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .div {
            height: 2000px;
        }
        p {
            height: 200px;
            color: white;
            background-color: blueviolet;
        }
    </style>
</head>
<body>
    <!-- 2. 通过getBoundingClientRect方法来获取元素的位置信息,然后加以判断 -->
     <div class="div"></div>
     <p>我出现啦</p>
     <script>
        function isContain(dom) {
            const totalHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
            const totalWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
            // 当滚动条滚动时,top、left、bottom、right时刻会发生改变
            const { top, right, bottom, left } = dom.getBoundingClientRect();
            return left >= 0 && top >= 0 && right <= totalWidth && bottom <= totalHeight;
        }
        const p = document.querySelector('p')
        window.onscroll = () => {
            if (isContain(p)) {
                document.body.style.backgroundColor = 'red'
            } else {
                document.body.style.backgroundColor = 'green'
            }
        }
     </script>
</body>
</html>

方法三、通过交叉检查器:Intersection Observer 来实现监听(推荐)

前置知识

MDN: https://developer.mozilla.org/zh-CN/docs/Web/API/Intersection_Observer_API

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .div {
            height: 2000px;
        }
        p {
            height: 200px;
            color: white;
            background-color: blueviolet;
        }
    </style>
</head>
<body>
    <!-- 3. 通过交叉检查器:Intersection Observer 来实现监听 -->
     <div class="div"></div>
     <p>我出现啦</p>
     <script>
        const p = document.querySelector('p')
        const observer = new IntersectionObserver(entries => {
            if (entries[0].isIntersecting) {
                document.body.style.backgroundColor = 'skyblue'
            } else {
                document.body.style.backgroundColor = 'orange'
            }
        }, {
            threshold: .2,  // 表示当子元素和父元素覆盖多少时触发回调函数。
        });
        observer.observe(p)
     </script>
</body>
</html>

网站公告

今日签到

点亮在社区的每一天
去签到