vueUse工具库之useIntersectionObserver和useScroll的底层实现原理

前言
这几天在面试时,面试官问我用过哪些vueUse中的工具函数或者说是hook,我说了useIntersectionObserver(用来判断元素是否进行可视区域的),useScroll(用来判断滚顶条下滑距离的),面试官问我明白这两个hook的原理吗,当时只是简单说了一下思路,现在使用原生js来实现一下。

useIntersectionObserver

这个hook的作用其实就是判断某元素是否进入了可视区域。
原理图奉上:
在这里插入图片描述
若认为:当图片的边缘进入可视区域时,就算该元素进入了可视区域,那么不难理解公式就是:
公式: offsetTop - scrollTop <= clientHeight
(这里的offsetTop、scrollTop、clientHeight指的都是目标元素的属性)
解释概念:
offsetTop:指的是元素距离网页页头的距离(不局限于当前页面)。
scrollTop:指的是滚动条滑动的距离。
clientHeight:指的是当前设备可视区域的高度。

代码实现

思路一:

    <style>
        body {
            height: 3000px;
        }
        .box {
            width: 100px;
            height: 100px;
            background-color: skyblue;
            margin-top: 1500px;
        }
    </style>
    	// 获取目标元素
        let box = document.querySelector('.box')
        
        // 设备高度
        let deviceHeight = document.documentElement.clientHeight

        // 定义动态判断元素是否位于可视区域的方法
        function isElementInVisible(){
            let scrollTop = document.documentElement.scrollTop
            let offsetTop = box.offsetTop
            if(offsetTop - scrollTop <= deviceHeight){
                console.log('进入了可视区域')
            }else {
                console.log('尚未进入可视区域')
            }
        }

        window.onscroll = isElementInVisible

在这里插入图片描述
注意:如果单纯给scroll事件绑定回调可能导致严重的性能问题,因此一般交给scroll事件的回调应使用防抖做处理

思路二:
使用 Element.getBoundingClientRect() 方法返回一个 DOMRect 对象,其提供了元素的大小及其相对于视口的位置。

		function isElementInVisible(){
            let deviceHeight = document.documentElement.clientHeight
            let domRect = box.getBoundingClientRect()
            if(domRect.top <= domRect) {
                console.log('进入了可视区域')
            }else {
                console.log('尚未进入可视区域')
            }
        }
        
        window.onscroll = isElementInVisible

思路三:
使用js原生的IntersectionObserver。
MDN解释: IntersectionObserver 接口(从属于 Intersection Observer API)提供了一种异步观察目标元素与其祖先元素或顶级文档视口(viewport)交叉状态的方法。

		let intersectionObserver = new IntersectionObserver((entries) => {
            if(entries[0].intersectionRatio <= 0) return 
            console.log("进入了可视区域")
        })
        intersectionObserver.observe(document.getElementsByClassName('box')[0])

useScroll
这个hook的作用就是获得滚动条的一些参数,如滚动条的下滑距离。

		// 方法一
 		document.addEventListener('scroll',(e) => {
            console.log(Math.floor(document.documentElement.scrollTop))
        })
        // 方法二
        document.addEventListener('scroll',(e) => {
            console.log(Math.floor(window.pageYOffset))
        })

效果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

WongLeer

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

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

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

打赏作者

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

抵扣说明:

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

余额充值