防止历史传播到父窗口
Posted
技术标签:
【中文标题】防止历史传播到父窗口【英文标题】:Prevent history propagation to the parent window 【发布时间】:2014-09-21 22:02:31 【问题描述】:我有 2 个简单的 html 页面:父页面和子页面。父级将子级存储在 iframe
.
父.html:
<html>
<head></head>
<body>
<input type="text" id="text" />
<input type="button" value="change hash" onclick="javascript:changeHash()" />
<iframe src="Child.html"></iframe>
<script type="text/javascript">
function changeHash ()
window.location.hash = document.getElementById('text').value;
</script>
</body>
</html>
还有 Child.html:
<html>
<head></head>
<body>
<input type="button" value="go back" onclick="javascript:goBack()" />
<script type="text/javascript">
function goBack ()
this.history.back();
</script>
</body>
</html>
我使用 更改哈希 按钮将多个哈希添加到历史记录。当我按下iframe
内的返回 按钮时 - 父页面的哈希值已更改。这似乎是spec 的行为。
所以问题是:是否可以防止从 iframe 返回到其父页面的传播?所以我希望 iframe 不要更改父级的历史记录/哈希。
注意:go
函数的行为相同(实际上,go(-1)
与 back()
相同)。
【问题讨论】:
如果iframe可以和parent通信,你就不能恢复丢失的hash吗?速度很快,没人会注意到。 @vsync,问题在于外部页面哈希hashchange
事件订阅,这就是导航的完成方式。所以应用程序会将用户导航回来。
尝试自己实现一个history navigation
堆栈(例如使用localStorage)并将goBack
函数更改为不依赖window.history
。
@php-dev,当然,这是一个解决方案。但这只是一种有趣的行为,现在它只是一种“挑战”。
【参考方案1】:
我认为不使用框架是不可能做到这一点的,但我有一个可以(部分)解决这个问题的解决方案。
首先,我想更改对象history
并重新定义它,但这是不可能的,因为它是窗口内的一个属性,不可写。但我们可以重新定义history
中的函数。
这就是导致我重新定义函数back()
的原因,而不是让history
对象完成他的工作,我们必须find the previous url 并更改文档(子)的位置。
在你是 Child.html
时,像这样重新定义函数 back()
:
history.back = function ()
document.location = document.referrer;
我们在这个函数中遇到的问题是,一旦加载了父文档,并且iframe(子)也加载了,子的document.referrer
返回父的url
所以,在更改document.location
之前,让我们测试一下document.referrer
是否与父母的网址不同(没有锚点)
history.back = function ()
var url = window.parent.document.location.href.split("#")[0];
if(document.referrer!=url)
document.location = document.referrer;
最后,这是我找到的解决方案,不幸的是它有一个问题,就是你不能重新定义函数forward()
让你去下一个url,不可能找到下一个url,并且document.referrer
返回您来自的页面的 url,它可以是上一页或下一页。但您仍然可以在 iframe 内导航而无需更改父位置。
【讨论】:
感谢您的回复!但它只适用于背部。还有一种返回的能力 -history.go(-1)
。实际上,可以覆盖 go
函数,但它可以导航 2,3,... 后退。如果退后 2 步以上,document.referrer
将不起作用。
是的,你是对的,但不要忘记 history.go
改变了父窗口的 url以上是关于防止历史传播到父窗口的主要内容,如果未能解决你的问题,请参考以下文章