内のコンテンツを表示するナビゲーション ページを作成していますiframe
。要件は、現在読み込まれているページに対応するナビゲーション リンクが強調表示されていることです。フレームの内容は私の手に負えません。ユーザーがブラウザで戻る/進むボタンを使用すると、問題が発生します。
アイデアは、history.replaceState
ナビゲーション リンクに関する情報をページに関連付け、popstate
イベント時にナビゲーション パネルの状態を復元するために使用することでした。コンテンツがAJAX経由でアプリケーションにロードされた場合、それは完全に機能しました。
iframe
ナビゲーションの場合history
、トップウィンドウのオブジェクトは変更されないので、 で作業するcontentWindow
必要があり、同じドメインのページのみをサポートするように制限します。
問題は、イベントにサブスクライブできなかったことです。次のコードは機能しません。
$(window).on('popstate', function () { handleHistory('popstate@window'); });
$('#frame').on('popstate', function () { handleHistory('popstate@iframe'); });
$($('#frame')[0].contentWindow).on('popstate', function () { handleHistory('popstate@iframe.window'); });
$('#frame')[0].contentWindow.onpopstate = function () { handleHistory('popstate@iframe.window'); };
後者の場合は後履歴ナビcontentWindow.onpopstate
ですnull
。
最後に、load
イベントを使用しようとしましたが、機能しましたが、すべてのページ リソースが読み込まれるまで待機するため、起動するまでにかなりの遅延があります。
$('#menu a').click(function() {
// ...
$('#frame').one('load', function() {
frameWindow.history.replaceState({ linkId: link.id },frameWindow.document.title, frameWindow.location.href);
});
// ...
});
$('#frame').load(function () { handleHistory('load@iframe'); });
私が試した別のアプローチcontentWindow.location.href
は、タイマーをポーリングして、より早く反応することでした。一見するとうまくいきましたが、その後、履歴レコードがブラウザーから消えることがあることに気付きました (少なくとも Firefox では)。
var isLoading = false;
$('#menu a').click(function() {
// ...
isLoading = true;
$('#frame').one('load', function() { isLoading = false; });
(function poll () {
var frameWindow = getFrameWindow();
if (getFrameWindow().location.href == link.href) {
frameWindow.history.replaceState({ linkId: link.id },frameWindow.document.title, frameWindow.location.href);
} else {
setTimeout(poll, 100);
}
})();
// ...
});
setInterval(function () {
if (!isLoading) {
handleHistory('timer');
}
}, 100);
内部の履歴を追跡する他の良い方法はありますiframe
か? おそらく私はいくつかの間違いを犯しましたか?おそらく、コンテンツのドメインに関係なくこれを行う方法さえありますか?
ソース コードとデモ ページは次のとおりです (スクリプトの動作をわかりやすくするために遅延が追加されています)。
onload アプローチ: src デモ
タイマー アプローチ: src デモ