我有一个窗口'onscroll'事件的监听器。在那个处理程序中,我需要以某种方式弄清楚触发事件的原因,例如:我正在运行一个触发window.scrollTo(x,y)的动画,如果事件是由动画触发的,则侦听器应该有不同的行为。更准确地说,如果用户在动画运行时滚动,我必须停止动画。甚至可以在触发window.scrollTo(x,y)时将上下文传递给事件处理程序,还是有一些hacky解决方法来实现这个目的?
以下是我想要实现的一些伪代码:
let isAnimationRunning = false
function onScrollHandler(e) {
const isTriggeredByOnAnimationTick = // how to figure that one out???
if (isAnimationRunning && !isTriggeredByOnAnimationTick) {
stopAnimation()
}
// do something else
}
// called every key frame (requestAnimationFrame)
function onAnimationTick(scrollY) {
// will trigger onscroll handler at some point in time
window.scrollTo(0, scrollY)
}
window.addEventListener('scroll', onScrollHandler)
runAnimation(onAnimationTick)
我已经考虑过在移动设备上使用不同的处理程序来处理鼠标滚轮和触摸事件。但是,通过这种方法,我遇到了两个问题:
答案 0 :(得分:0)
不是检测用户滚动,而是检查我们想要降落的位置。如果更改,则用户可能已滚动:
function scroll(x,y,end,interrupt,requireX, requireY){
//the movement applied after each loop
const speedX = 1, speedY = 1;
//check if the scrolled amount is not what we expect
if(requireX && requireX !== scrollX ||
requireY && requireY !== scrollY ) return interrupt();
//check if we reached our position
if( Math.abs(x - scrollX) < speedX &&
Math.abs(y - scrollY) < speedY
) return end();
//now finally scroll using window.scrollBy
scrollBy(
x > scrollX ? speedX : -speedX,
y > scrollY ? speedY : -speedY
);
//next iteration in 10ms
setTimeout(scroll, 10, x, y, end, interrupt,scrollX, scrollY) ;
}
然后整个事情可以用作:
scroll(
1000, //x to scroll to
0, //y to scroll to
_=>alert("finish"), //end handler
_=>alert("interrupt") //user interrupted handler
);