ブラウザの戻るボタンイベントを検出する方法 - クロスブラウザで質問する

ブラウザの戻るボタンイベントを検出する方法 - クロスブラウザで質問する

ユーザーがブラウザの戻るボタンを押したかどうかを確実に検出するにはどうすればよいでしょうか?

システムを使用して、単一ページの Web アプリケーション内でページ内戻るボタンの使用を強制するにはどうすればよいですか#URL?

いったいなぜブラウザの戻るボタンは独自のイベントを発生させないのでしょうか?

ベストアンサー1

(注: Sharky のフィードバックに従って、バックスペースを検出するコードを追加しました)

そこで、私は SO でこれらの質問を頻繁に目にし、最近、戻るボタンの機能を制御するという問題に自分自身で遭遇しました。自分のアプリケーション (ハッシュ ナビゲーションを使用したシングル ページ) に最適なソリューションを数日間探した結果、戻るボタンを検出するためのシンプルでクロス ブラウザーのライブラリ不要のシステムを思いつきました。

ほとんどの人は以下を使用することをお勧めします:

window.onhashchange = function() {
 //blah blah blah
}

ただし、この関数は、ユーザーがページ内要素を使用してロケーション ハッシュを変更する場合にも呼び出されます。ユーザーがクリックしてページが前後に移動すると、最適なユーザー エクスペリエンスが得られません。

私のシステムの概要を説明すると、ユーザーがインターフェースを移動するときに、以前のハッシュで配列を埋めていきます。次のようになります。

function updateHistory(curr) {
    window.location.lasthash.push(window.location.hash);
    window.location.hash = curr;
}

非常に簡単です。これは、クロスブラウザのサポートと古いブラウザのサポートを確実にするために行います。新しいハッシュを関数に渡すだけで、関数はそれを保存し、ハッシュを変更します (その後、ブラウザの履歴に保存されます)。

また、配列を使用してユーザーをページ間で移動するページ内戻るボタンも利用しますlasthash。次のようになります。

function goBack() {
    window.location.hash = window.location.lasthash[window.location.lasthash.length-1];
    //blah blah blah
    window.location.lasthash.pop();
}

これにより、ユーザーは最後のハッシュに戻り、その最後のハッシュが配列から削除されます (現時点では進むボタンはありません)。

では、ユーザーがページ内の戻るボタンやブラウザボタンを使用したかどうかをどのように検出すればよいのでしょうか?

最初は を調べましたwindow.onbeforeunloadが、役に立ちませんでした。これは、ユーザーがページを変更する場合にのみ呼び出されます。これは、ハッシュ ナビゲーションを使用するシングル ページ アプリケーションでは発生しません。

そこで、さらに調べてみると、フラグ変数を設定するという推奨事項を見つけました。私の場合、これに関する問題は、設定しようとしてもすべてが非同期であるため、ハッシュ変更の if ステートメントに間に合うように設定されないことが常にあることです。.onMouseDownクリック時に常に呼び出されるわけではなく、onclick に追加しても十分な速さでトリガーされません。

ここで、 と の違いを調べ始めましたdocumentwindow最終的な解決策は、 を使用してフラグを設定しdocument.onmouseover、 を使用して無効にすることでしたdocument.onmouseleave

ユーザーのマウスがドキュメント領域 (つまり、レンダリングされたページですが、ブラウザ フレームは除きます) 内にある間、ブール値は に設定されますtrue。マウスがドキュメント領域を離れるとすぐに、ブール値は に切り替わりますfalse

この方法で、次のように変更できますwindow.onhashchange

window.onhashchange = function() {
    if (window.innerDocClick) {
        window.innerDocClick = false;
    } else {
        if (window.location.hash != '#undefined') {
            goBack();
        } else {
            history.pushState("", document.title, window.location.pathname);
            location.reload();
        }
    }
}

のチェックに注意してください#undefined。これは、配列に利用可能な履歴がない場合、 が返されるためですundefined。これを使用して、イベントを使用して終了するかどうかをユーザーに尋ねますwindow.onbeforeunload

つまり、簡単に言うと、必ずしもページ内の戻るボタンや履歴を保存するための配列を使用していない人向けです。

document.onmouseover = function() {
    //User's mouse is inside the page.
    window.innerDocClick = true;
}

document.onmouseleave = function() {
    //User's mouse has left the page.
    window.innerDocClick = false;
}

window.onhashchange = function() {
    if (window.innerDocClick) {
        //Your own in-page mechanism triggered the hash change
    } else {
        //Browser back button was clicked
    }
}

これで完了です。ハッシュ ナビゲーションに関して、戻るボタンの使用とページ内要素を検出するシンプルな 3 つの方法をご紹介します。

編集:

ユーザーがバックスペースを使用して戻るイベントをトリガーしないようにするには、次のコードを含めることもできます(@thetoolmanに感謝します)。この質問):

$(function(){
    /*
     * this swallows backspace keys on any non-input element.
     * stops backspace -> back
     */
    var rx = /INPUT|SELECT|TEXTAREA/i;

    $(document).bind("keydown keypress", function(e){
        if( e.which == 8 ){ // 8 == backspace
            if(!rx.test(e.target.tagName) || e.target.disabled || e.target.readOnly ){
                e.preventDefault();
            }
        }
    });
});

おすすめ記事