2017-10-12 12 views
2

私はwindowの 'onscroll'イベントのリスナーを持っています。そのハンドラでは、何がイベントをトリガしたかを何らかの形で把握する必要があります。イベントがアニメーションによってトリガされた場合、window.scrollTo(x、y)をトリガするアニメーションを実行していて、リスナは異なる動作をする必要があります。より正確には、アニメーションの実行中にユーザーがスクロールした場合、アニメーションを停止する必要があります。 window.scrollTo(x、y)をトリガするときにイベントハンドラにコンテキストを渡すことも可能ですか?これを達成するためのいくつかのハックの回避策がありますか?ここで'onscroll'イベントのソースを特定する

は私が達成しようとしているもののいくつかの擬似コードです:

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) 

私はすでにモバイル上のマウスホイールやタッチイベントのために別のハンドラを使用して考えました。

  1. 一つは、このように、タッチジェスチャーが終了した後に減速され、スクロール、モバイルデバイスではスクロールバー
  2. を経由してユーザーがスクロールするかどうか、を把握するために、別のハックを思い付くことがあります。しかし、そのアプローチと私は2つの問題に遭遇しましたonscollハンドラを使わずにスクロールイベントがいつ止まるかはわかりません。

答えて

0

ユーザーのスクロールを検出する代わりに、私たちが着陸したい位置を確認することができます。それが変化した場合、ユーザーはおそらく、スクロールした:

scroll(
    1000, //x to scroll to 
    0, //y to scroll to 
    _=>alert("finish"), //end handler 
    _=>alert("interrupt") //user interrupted handler 
); 

Try it

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

全体のことのように、次に使用可能です

関連する問題