React中onScroll事件不触发如何解决?实现滚动关联卡片淡入淡出动画
React滚动事件不触发排查及滚动驱动动画实现方案
事件不触发根因
React 的 onScroll 事件仅会在绑定的元素自身发生滚动行为时触发,你当前的代码没有触发事件,是因为滚动行为实际发生在全局 window 对象上,绑定事件的 .outer-container 容器本身不具备滚动能力。
解决方案(二选一即可)
方案1:给外层容器添加滚动能力
给 .outer-container 添加对应的滚动属性,让滚动行为发生在容器内,绑定的 onScroll 事件即可触发:
/* styles.css */ body { margin: 0; overflow: hidden; /* 避免全局滚动,防止出现双滚动条 */ } .outer-container { height: 100vh; overflow-y: scroll; overscroll-behavior: contain; /* 禁止滚动冒泡到外层 */ }
方案2:直接监听全局window滚动事件
如果不需要容器滚动,只需在组件挂载时给window绑定滚动监听,卸载时移除避免内存泄漏,修改代码如下:
import React, {useState, useEffect} from 'react' import './styles.css' import Card1 from './Card1' function App() { const [idx, setIdx] = useState(1); const iterate = () => { console.log('scrolled') } useEffect(() => { window.addEventListener('scroll', iterate) // 组件卸载时移除监听 return () => window.removeEventListener('scroll', iterate) }, []) return ( <div className="outer-container"> <Card1 num = {idx}/> <Card1 num = {idx}/> <Card1 num = {idx}/> <Card1 num = {idx}/> <Card1 num = {idx}/> <Card1 num = {idx}/> </div>); } export default App;
滚动驱动卡片淡入淡出效果实现逻辑
事件触发后,可按照以下逻辑实现苹果官网同款效果:
- 每个卡片高度为100vh,通过滚动距离除以视口高度得到当前滚动进度
- 对每个卡片调用
getBoundingClientRect()获取其在视口中的位置,根据卡片和视口的交叉比例动态计算透明度:比如卡片完全处于视口中心时透明度为1,卡片顶部/底部刚接触视口边缘时透明度为0 - 追求更高性能可替换为
IntersectionObserver监听元素交叉状态,减少scroll事件高频触发的性能消耗
内容的提问来源于stack exchange,提问作者sharkeater123
相关产品推荐
相关产品推荐

