React技巧之检查元素是否可见
原文链接:https://bobbyhadz.com/blog/react-check-if-element-in-viewport
正文从这开始~
总览
在React中,检查元素是否在视口范围内:
- 在元素上设置
ref
属性。 - 使用
IntersectionObserver
API来跟踪元素是否与视口相交。
import {useEffect, useRef, useState, useMemo} from 'react';
export default function App() {
const ref1 = useRef(null);
const ref2 = useRef(null);
const isInViewport1 = useIsInViewport(ref1);
console.log('isInViewport1: ', isInViewport1);
const isInViewport2 = useIsInViewport(ref2);
console.log('isInViewport2: ', isInViewport2);
return (
<div>
<div ref={ref1}>Top div {isInViewport1 && '| in viewport ✅'}</div>
<div style={{height: '155rem'}} />
<div ref={ref2}>Bottom div {isInViewport2 && '| in viewport ✅'}</div>
</div>
);
}
function useIsInViewport(ref) {
const [isIntersecting, setIsIntersecting] = useState(false);
const observer = useMemo(
() =>
new IntersectionObserver(([entry]) =>
setIsIntersecting(entry.isIntersecting),
),
[],
);
useEffect(() => {
observer.observe(ref.current);
return () => {
observer.disconnect();
};
}, [ref, observer]);
return isIntersecting;
}
该示例向我们展示了,如何检查元素是否在视口范围内。IntersectionObserver
API使我们能够检查一个给定的元素是否与文档相交。
useIsInViewport
钩子接收一个指向我们想要追踪的元素的ref
对象。
IntersectionObserver
IntersectionObserver
构造函数接收一个函数,该函数被调用时带有一个entry
数组。entry
是一个数组,其包含了所有的obeserver
的目标元素。这些元素的可见度已经高于或低于intersection observer
的比率之一。
每个entry
都描述了一个给定元素与根元素(文档)相交的程度。我们解构了这个entry
,因为我们的IntersectionObserver
只能跟踪一个元素(就是我们设置ref
的那个元素)。
我们调用observe()
方法,将我们要跟踪的元素传给它 - observer.observe(ref.current)
。
每当元素进入视口或者存在于视口中时,我们传递给IntersectionObserver()
构造函数的函数就会被调用,然后更新state
变量。
// ?️ gets called every time element enters or leaves viewport
new IntersectionObserver(([entry]) =>
setIsIntersecting(entry.isIntersecting),
)
如果我们设置ref
对象的元素在视口中,useIsInViewport
钩子将会返回true
。如果元素不在视口中,该钩子将会返回false
。
需要注意的是,在初始渲染时,useIsInViewport
钩子将会返回false
。因为我们为useState
传递的初始值为false
。const [isIntersecting, setIsIntersecting] = useState(false);
如果你想跟踪钩子的返回值的变化,请使用useEffect
钩子,并将该值添加到钩子的依赖关系中。
const isInViewport1 = useIsInViewport(ref1);
console.log('isInViewport1: ', isInViewport1);
useEffect(() => {
// ?️ listen for changes
console.log(isInViewport1);
}, [isInViewport1]);
相关文章
- MagicAjax 使用介绍(翻译)
- 第三产业的企业的信息化系统的价格机制
- MagicAjax 简单使用介绍(翻译)
- (转帖)asp.net调试错误解决方法收集(1)
- MagicAjax Features (MagicAjax特点 0.30版) (翻译)
- 疑是Microsoft Enterprise Library June 2005的一个小bug (续)
- 疑是Microsoft Enterprise Library June 2005的一个小bug
- MagicAjax 0.30版的更新(翻译)
- 【愚公系列】2022年12月 .NET CORE 即时通讯-使用SignalR进行井字游戏
- Winform自动更新之AutoUpdater.NET
- [MySQL] 理解InnoDB并发高的原因
- 自己动手基于 Redis 实现一个 .NET 的分布式锁类库
- [MySQL] in 子查询出现DEPENDENT SUBQUERY问题
- [MySQL] group by 聚合函数的原理和聚合限制原因SELECT list is not in GROUP BY clause and contains nonaggregated column
- [MySQL]mysql的ANY_VALUE()函数 解决 ONLY_FULL_GROUP_BY 模式
- [日常]windows下kill进程工具taskkill
- [CSS] 纯CSS的前端图标icon库并且修改大小和颜色
- [PHP] php中的索引数组和数组顺序问题
- [日常] 修改编辑word中的页眉页脚
- [nginx]配置nginx支持websocket解决返回400错误问题