web-dev-qa-db-ja.com

history.pushState-機能していませんか?

リロードせずにhtmlを変更したい。私はそれを次のようにします:

$('#left_menu_item').click(function(e) {
    if (!!(window.history && history.pushState)) {
        e.preventDefault();
        history.pushState(null, null, newUrl);
    }
});

正常に動作します。しかし、「戻る」ボタンで戻りたい場合-ブラウザは前のURLを変更しますが、ページを再読み込みしません。どうして?

17
indapublic

この動作は予期されたものであり、履歴スタックの操作の 仕様 に準拠しています。

これは説明が比較的複雑な問題です。しかし、簡単に言えば、これを次のように考えてください。ユーザーが履歴スタックに(pushStateなどを使用して)プッシュした履歴エントリは、そこから移動したときにページの読み込みに値しません。

どうして? この動作は良いことであり、再読み込みを強制されずに開発者がページをより詳細に制御できるようにする意図と一致しています(ajaxのように考えると、以前はデータのフェッチなどのページの再読み込みによってのみ可能でしたが、 XMLHttpRequest オブジェクトを使用してページを再読み込みせずに実行できるようになりました。戻るボタンをクリックしたときにページを再読み込みする動作を模倣したい場合は、location.reload()を呼び出すだけです。 window.onpopstateイベントを処理するとき


どうやって? これはあなたの質問の範囲外かもしれませんが、私たちが話していることを説明するためにそこに置きたかっただけです

既存の例を使用して説明しましょう here (抜粋されたテキストはitalicisedになります):

仮定 http://mozilla.org/foo.html は次のJavaScriptを実行します:

var stateObj = { foo: "bar" };
history.pushState(stateObj, "page 2", "bar.html");

これにより、URLバーに http://mozilla.org/bar.html が表示されますが、ブラウザがbar.htmlをロードしたり、 bar.htmlが存在することを確認します。

実際のページロードに関連付けられていない履歴スタックにエントリを作成していると考えてください。むしろ、「偽の」ページロードです(つまり、JavaScriptを使用してDOMを操作し、HTMLを挿入しています)。

ユーザーが http://google.com に移動し、クリックして戻ったとします。この時点で、URLバーには http://mozilla.org/bar.html が表示され、ページには、stateObjのコピーが含まれる状態オブジェクトを持つpopstateイベントが表示されます。ページ自体はfoo.htmlのようになりますが、popstateイベント中にページのコンテンツが変更される可能性があります。

ここでのポイントは、bar.htmlが元の http://mozilla.org/foo.html ..の上にある偽の履歴エントリであるため、URLに表示される http://mozilla.org/bar.html ただし、コンテンツはfooに属します(この例では、bar.htmlをプッシュしたときにdomのコンテンツを操作しなかったことに注意してください。たとえば、そのコンテンツも表示されます)。ここで重要なことは、ページ リロード!..履歴スタックに本物のエントリがあるページを提供しているため(たとえURLにある場合でも、履歴スタックの偽のエントリに関連付けられているURLを表示しています)。

また、この議論をpopstateイベントを手動で処理するページから分離します。これは別の話であり、事態を複雑にします。

もう一度クリックすると、URLは http://mozilla.org/foo.html に変わり、ドキュメントは今回は別のpopstateイベントを取得しますnull状態オブジェクト。ここでも、前の手順の内容からドキュメントの内容が変更されることはありませんが、popstateイベントを受け取ったときにドキュメントの内容が手動で更新されることがあります。

ここ..ページ 読み込まれません!..これは、偽の履歴スタックエントリから実際のエントリへの転送を行っているためです(そして、実際のエントリは前のステップで既にロードされているので、ページがリロードされ、それだけです)。

例としてはこれで終わりです。コンセプトは説明が難しいので、実際のページと偽のページの組み合わせをクリックしてコードをテストすると、ページが実際に読み込まれるタイミングと読み込まれないパターンが表示されます。

38
abbood
window.onpopstate = function(event) {    
    if(event && event.state) {
        location.reload(); 
    }
}

これは私が使うものです:)

13
Jimbob