当前位置:   article > 正文

【JS篇】通过 useEventListener 实现监听滚动条的滚动结束事件

useeventlistener

功能背景

项目中遇到需要监听当前用户操作的滚动容器的滚动位置,用以获得当前用户正在查看的内容模块,便于制作导航条展示用户当前所查看的模块(类似页内导航功能)。故想要通过实时监听滚动位置,根据判断滚动停止来执行相应事件,但js中并没有监听滚动停止事件,只能通过在滚动的监听事件中增加定时器来判断滚动是否停止。
在这里插入图片描述

功能实现方式分析

  1. 初始时,使用 ahooks 的 useScroll,实时获取滚动位置数据进行操作,实现功能,但使用过程中发现滚动条不断改变位置的同时,scroll的值也在不断更新,查看源码发现在监听滚动条滚动过程中,也在不断进行setState操作,当页面功能复杂,dom节点较多的情况下,可能严重影响性能和体验。
// ahooks 中 useScroll 的源码部分:setPosition 执行的是内部封装的 useRafState, 本质上也是进行了 setState 操作
if (shouldUpdateRef.current(newPosition)) {
	setPosition(newPosition);
}
  • 1
  • 2
  • 3
  • 4
  1. 后来考虑通过 ahooks 的 useEventListener 监听滚动条滚动事件实现。但考虑到性能问题,需要判断滚动结束后再去获得滚动位置数据,并进行数据的操作。
  2. 通过设置监听器,在不停地触发滚动时,不会执行定时器内的方法,当滚动停止时,定时器前后两次获取的 scrollTop 应该是相同的,可以此作为判断依据。
  const scrollRef = useRef(null);
  // 滚动结束位置信息
  const [scrollPosition, setScrollPosition] = useState({top: 0, left: 0});
  const timer = useRef(null);
  const topValue = useRef(0);
  
  // 滚动事件监听
  useEventListener(
    'scroll',
    () => {
      clearTimeout(timer.current)
      topValue.current = scrollRef.current.scrollTop;
	  timer.current = setTimeout(()=>{
        if(scrollRef.current.scrollTop === topValue.current) {
          const position = {
            top: scrollRef.current.scrollTop,
            left: scrollRef.current.scrollLeft
          };
          setScrollPosition(position)
		  // TODO 执行后续滚动结束的事件
          // ...
        }
      }, 300);
    },
    { target: scrollRef },
  );

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

页面布局部分:container 为滚动容器,div1、div2、div3为滚动内容,滚动停止时,将获取当前滚动条的scrollTop, 并以此判断当前停留在哪个div上,从而进行标记,以此实现页面导航功能。

	<div className='container' style={{position: 'relative'}} ref={scrollRef}>
        <div data-anchorpointid='div1'>div1</div>
        <div data-anchorpointid='div2'>div2</div>
        <div data-anchorpointid='div3'>div3</div>
	</div>
  • 1
  • 2
  • 3
  • 4
  • 5
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/275123
推荐阅读
相关标签
  

闽ICP备14008679号