onpopstateに追加するハンドラーごとに特別な対策を講じたくない場合は、私のソリューションが興味深いかもしれません。このソリューションの大きな利点は、ページの読み込みが完了する前にonpopstateイベントを処理できることです。
onpopstateハンドラーを追加する前にこのコードを1回実行するだけで、すべてが期待どおりに機能するはずです(別名Mozilla ^^)。
(function() {
// There's nothing to do for older browsers ;)
if (!window.addEventListener)
return;
var blockPopstateEvent = document.readyState!="complete";
window.addEventListener("load", function() {
// The timeout ensures that popstate-events will be unblocked right
// after the load event occured, but not in the same event-loop cycle.
setTimeout(function(){ blockPopstateEvent = false; }, 0);
}, false);
window.addEventListener("popstate", function(evt) {
if (blockPopstateEvent && document.readyState=="complete") {
evt.preventDefault();
evt.stopImmediatePropagation();
}
}, false);
})();
使い方:
ドキュメントが読み込まれると、Chrome、Safari、およびおそらく他のWebkitブラウザがonpopstateイベントを発生させます。これは意図されたものではないため、ドキュメントが読み込まれた後の最初のイベントループcicleまでpopstateイベントをブロックします。これは、preventDefaultおよびstopImmediatePropagation呼び出しによって行われます(stopPropagation stopImmediatePropagationがすべてのイベントハンドラー呼び出しを即座に停止するのとは異なります)。
ただし、Chromeが誤ってonpopstateを起動した場合、ドキュメントのreadyStateはすでに「完了」になっているため、ドキュメントの読み込みが完了する前に起動されたopopstateイベントで、ドキュメントが読み込まれる前にonpopstateを呼び出すことができます。
アップデート2014-04-23:ページが読み込まれた後にスクリプトが実行されるとpopstateイベントがブロックされるバグを修正しました。