1. ホーム
  2. javascript

[解決済み] スクロールイベントがユーザーによって作成されたかどうかを検出する

2023-02-01 06:02:16

質問

スクロールイベントがブラウザによって行われたのか、ユーザーによって行われたのかを見分けることは可能でしょうか。具体的には、戻るボタンを使用するとき、ブラウザは最後の既知のスクロール位置にジャンプすることがあります。スクロール イベントにバインドする場合、これがユーザーによって引き起こされたのか、それともブラウザーによって引き起こされたのかをどのように見分けることができますか?

$(document).scroll( function(){ 
    //who did this?!
});

ブラウザでスクロールが発生する状況には3種類ありますね。

  1. ユーザーが何らかのアクションを実行した。たとえば、マウス ホイール、矢印キー、ページ アップ/ダウン キー、ホーム/エンド キーを使用する、スクロール バーをクリックする、または親指をドラッグする、などです。
  2. ブラウザが自動的にスクロールする。たとえば、ブラウザの戻るボタンを使用すると、最後の既知のスクロール位置に自動的にジャンプします。
  3. Javascript がスクロールします。例えば element.scrollTo(x,y) .

どのように解決するのですか?

残念ながら、それを直接伝える方法はありません。

私が言いたいのは、もしあなたが リデザイン このようなフローに依存しないように、アプリを再設計できるのであれば、そうしてください。

そうでない場合は ワークアラウンド

私が思いつくのは、ユーザーが開始したスクロールを追跡し、スクロールがブラウザによって引き起こされたのか、ユーザーによって引き起こされたのかを確認するためにそれをチェックすることです。

これはかなりうまくいく例です (ただし、jQuery の履歴に問題があるブラウザを除きます)。

完全にテストできるようにするには、これをローカルで実行する必要があります(jsFiddle/jsbinはコンテンツをiFrame化するため、あまり適していません)。

ここに テストケース を検証してみました。

  • ページの読み込み userScrollfalse
  • マウス/キーボードを使ったスクロール-。 userScroll となる true
  • リンクをクリックするとページ下にジャンプします。 userScroll となる false
  • 戻る/進むをクリックします。 userScroll になる false ;

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="utf-8" /> 
    <script src="http://code.jquery.com/jquery-1.6.1.min.js"></script> 
    <script type="text/javascript" src="https://raw.github.com/tkyk/jquery-history-plugin/master/jquery.history.js"></script> 
</head> 
<body> 
    <span> hello there </span><br/> 
    <a href="#bottom"> click here to go down </a> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <a name="bottom"> just sitting </a> 
</body> 
<script type="text/javascript"> 

var userScroll = false;     

function mouseEvent(e) { 
    userScroll = true; 
} 


$(function() { 

    // reset flag on back/forward 
    $.history.init(function(hash){ 
        userScroll = false; 
    }); 

    $(document).keydown(function(e) { 
        if(e.which == 33        // page up 
           || e.which == 34     // page dn 
           || e.which == 32     // spacebar
           || e.which == 38     // up 
           || e.which == 40     // down 
           || (e.ctrlKey && e.which == 36)     // ctrl + home 
           || (e.ctrlKey && e.which == 35)     // ctrl + end 
          ) { 
            userScroll = true; 
        } 
    }); 

    // detect user scroll through mouse
    // Mozilla/Webkit 
    if(window.addEventListener) {
        document.addEventListener('DOMMouseScroll', mouseEvent, false); 
    }

    //for IE/OPERA etc 
    document.onmousewheel = mouseEvent; 


    // to reset flag when named anchors are clicked
    $('a[href*=#]').click(function() { 
        userScroll = false;
    }); 

      // detect browser/user scroll
    $(document).scroll( function(){  
        console.log('Scroll initiated by ' + (userScroll == true ? "user" : "browser"));
    });
}); 
</script> 
</html>

注意事項

  • これは、ユーザーがマウスでスクロールバーをドラッグしたときのスクロールを追跡しません。これは、いくつかのより多くのコードで追加することができますが、私はあなたのための練習として残しました。
  • event.keyCodes はOSによって異なる可能性があるので、適切に変更する必要があるかもしれません。

これが役に立つことを願っています。