Javascript 确定'的来源;onscroll';事件

Javascript 确定'的来源;onscroll';事件,javascript,events,browser,onscroll,Javascript,Events,Browser,Onscroll,我有一个用于Windows的“onscroll”事件的侦听器。在该处理程序中,我需要以某种方式找出触发事件的原因,例如,我正在运行一个触发window.scrollTo(x,y)的动画,如果事件是由动画触发的,则侦听器应该具有不同的行为。更准确地说,如果用户在动画运行时滚动,我必须停止动画。当我触发window.scrollTo(x,y)时,是否有可能将上下文传递给事件处理程序,或者是否有一些黑客的解决方法来实现这一点 下面是我试图实现的一些伪代码: let isAnimationRunning

我有一个用于Windows的“onscroll”事件的侦听器。在该处理程序中,我需要以某种方式找出触发事件的原因,例如,我正在运行一个触发window.scrollTo(x,y)的动画,如果事件是由动画触发的,则侦听器应该具有不同的行为。更准确地说,如果用户在动画运行时滚动,我必须停止动画。当我触发window.scrollTo(x,y)时,是否有可能将上下文传递给事件处理程序,或者是否有一些黑客的解决方法来实现这一点

下面是我试图实现的一些伪代码:

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)
我已经考虑过在手机上使用不同的鼠标滚轮和触摸事件处理程序。然而,使用这种方法,我遇到了两个问题:

  • 一个人必须想出另一个黑客来弄清楚,用户是否通过滚动条滚动
  • 在移动设备上,触摸手势结束后滚动会减速,因此,如果不使用onscoll处理程序,我无法真正确定滚动事件何时停止

  • 与其检测用户滚动,不如检查我们想要降落的位置。如果发生变化,用户可能已滚动:

    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
    );