gpt4 book ai didi

javascript - 在 iframe 中处理历史导航

转载 作者:太空宇宙 更新时间:2023-11-04 13:19:51 34 4
gpt4 key购买 nike

我正在构建一个导航页面,在 iframe 中显示一些内容。要求是高亮当前加载页面对应的导航链接。框架内容是我无法控制的。当用户在其浏览器中使用后退/前进按钮时,问题就开始了。

想法是使用 history.replaceState 将导航链接的信息与页面相关联,并在 popstate 事件上恢复导航面板状态。当内容通过 AJAX 加载到应用程序时,它在其他情况下工作得很好。

iframe 导航的情况下,顶部窗口的 history 对象没有被修改,所以我应该使用 contentWindow,从而限制我自己 fto 仅支持来自同一域的页面。

问题是我无法订阅该事件。以下代码不起作用:

$(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.onpopstatenull

最后我尝试使用 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 以便更早使用react。乍一看它运行良好,但后来我注意到有时历史记录会从浏览器中消失(至少在 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 中是否有任何其他跟踪历史记录的好方法?可能我犯了一些错误?也许甚至有一种方法可以不考虑内容的域来做到这一点?


这是源代码和演示页面(添加了延迟以更好地说明脚本行为)。
加载方法:src demo
计时器方法:src demo

最佳答案

这确实不是一个令人满意的解决方案,但您可以在框架的加载事件中检查历史堆栈的大小。

<html>
<body>

<iframe src="http://w3c.org" class="xssFrame"></iframe>
<p class="output"></p>

<script>
var size = window.history.length;
var tempSize = null
//document.querySelector(".xssFrame").unload = function(){} //might need to set this handler to force load event on back click
document.querySelector(".xssFrame").onload = function () {
var delta = size - window.history.length;
document.querySelector(".output").innerHTML = "parent history: " + size + " combined history: " + window.history.length + " go " + (delta-1).toString()
if(tempSize === window.history.length) {
document.querySelector(".output").innerHTML = "go now" + (delta).toString()
window.history.go(delta)
} else {
tempSize = window.history.length
}


}
</script>
</body>
</html>

关于javascript - 在 iframe 中处理历史导航,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19452427/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com