我正在构建一个导航页面,该页面显示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
?可能我犯了一些错误?无论内容的域如何,也许甚至有办法做到这一点?