防止历史传播到父窗口

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

以上是关于防止历史传播到父窗口的主要内容,如果未能解决你的问题,请参考以下文章

防止 Angular HostListener 传播到父组件

如何将数据从新窗口传递到父窗口

滚动子窗口“溢出”到父窗口

如何在 Qt 中将消息从子窗口小部件发送到父窗口?

QT开发_弹出窗口禁用父窗口并移动到父窗口中心位置

将子窗口停靠到父窗口