javascript - 车轮事件触发多次反应
问题描述
我正在尝试实现整页滚动。我的问题是车轮事件经常触发两次。我在 vanilla js 上实现了它,并且效果很好。
const [ index, setIndex ] = useState(0);
const sectionWrapper = useRef();
const animationBreak = 750;
const maxIndex = 2;
let lastTime = 0;
useEffect(
() => {
const handleWheel = e => {
const sections = sectionWrapper.current.children;
const wheelDirection = e.wheelDelta;
const currentTime = new Date().getTime();
const isAnimationEnable = currentTime - lastTime > animationBreak;
if (!isAnimationEnable) return;
if (wheelDirection < 0 && index < maxIndex) {
setIndex(index + 1);
}
if (wheelDirection > 0 && index > 0) {
setIndex(index - 1);
}
sections[index].scrollIntoView({ behavior: 'smooth' });
lastTime = currentTime;
};
window.addEventListener('wheel', handleWheel);
return () => window.removeEventListener('wheel', handleWheel);
},
[ index ]
);
我尝试使用 lodash 的方法,如油门或去抖动。不适合我。
解决方案
您无需在每次索引更改时删除/重新分配事件处理程序,事件处理代码永远不会更改,您只需要访问最新index
状态即可。您可以通过在函数上使用回调来做到这一点,setX
例如
useEffect(() => {
const handleWheel = e => {
const sections = sectionWrapper.current.children;
const wheelDirection = e.wheelDelta;
const currentTime = new Date().getTime();
const isAnimationEnable = currentTime - lastTime > animationBreak;
if (!isAnimationEnable) return;
let index;
setIndex(i => index = i); // read most recent index
// use a temp var to get the new state value for scrolling later
let newIndex;
if (wheelDirection < 0 && index < maxIndex) {
setIndex(i => (newIndex = ++i)); // increment the current index by 1
}
if (wheelDirection > 0 && index > 0) {
setIndex(i => (newIndex = --i)); // decrement the current index by 1
}
sections[newIndex].scrollIntoView({ behavior: 'smooth' });
lastTime = currentTime;
};
window.addEventListener('wheel', handleWheel);
return () => window.removeEventListener('wheel', handleWheel);
}, []); // we no longer need any dependences here
推荐阅读
- javascript - 如何在 jscodeshift 中包装除导入之外的所有顶级语句和声明?
- image - Unable to render image on UI in jsp page of Spring MVC Application
- python - Merge multiple dataframes - how to assign column names automatically?
- soapui - READYAPI - Run multiple data per iteration on datasource
- android - Bazel + Android + Java8 complains about non-referenced API level 13
- sql - 下一篇:jdbc 如何允许 SQL Server 多条语句
- javascript - 如何按id过滤和获取数组?
- javascript - 在不使用 jquery 的情况下,如何在用户滚动 100px 后显示 div?
- ios - 我们可以检查允许应用程序请求跟踪切换是否打开
- c# - 如何使用 SocketIOClient 将 C# 连接到 SocketIO