重新加载 IFRAME 而不添加到历史记录

问题描述 投票:0回答:11

我正在更改 IFRAME 的

src
以便重新加载它,它工作正常,并在加载 HTML 时触发
onload
事件。

但它在历史中添加了一个条目,这是我不想要的。有什么方法可以重新加载 IFRAME 并且不影响历史记录吗?

javascript html iframe browser-history
11个回答
80
投票

使用replace()只是您自己的域iframe的一个选项。它无法在远程站点(例如:twitter 按钮)上工作,并且需要一些特定于浏览器的知识才能可靠地访问子窗口。

相反,只需删除 iframe 元素并在同一位置构造一个新元素即可。仅当您在 DOM 中修改

src
属性后才会创建历史记录项,因此请确保在追加之前设置它。

编辑:JDandChips 正确地提到您可以从 DOM 中删除、修改和重新附加。不需要构建新鲜的。


38
投票

您可以使用 JavaScript

location.replace
:

window.location.replace('...html');

将当前文档替换为 位于提供的 URL 中的一个。这 与 allocate() 方法的区别是 使用replace()后当前 页面不会保存在会话中 历史记录,这意味着用户不会 能够使用后退按钮 导航到它。


26
投票

就像 Greg 上面所说的那样,.replace() 函数就是如何做到这一点的。我似乎不知道如何回复他的答案*,但诀窍是引用 iFrames contentWindow 属性。

var ifr = document.getElementById("iframeId");
ifr.contentWindow.location.replace("newLocation.html"); 

*刚刚了解到我需要更多声誉才能对答案发表评论。


15
投票

重新创建 iframe 的另一种方法是从 DOM 中删除 iframe,更改 src,然后重新添加它。

在很多方面,这与

replace()
建议类似,但当我尝试使用 History.js 并手动管理状态时,我遇到了一些问题。

var container = iframe.parent();

iframe.remove();
iframe.attr('src', 'about:blank');

container.append(iframe);

10
投票

一种解决方案是使用

object
标签而不是
iframe
标签。

更换这个:

<iframe src="http://yourpage"/>

通过这个:

<object type="text/html" data="http://yourpage"/>

将允许您更新

data
属性而不影响历史记录。如果您使用声明性框架(例如
React.js
),而您不应该执行任何命令式命令来更新 DOM,那么这非常有用。

有关

iframe
object
之间差异的更多详细信息: 使用 Iframe 或对象标记将网页嵌入到另一个页面中


5
投票

尝试使用此功能将旧 iframe 替换为从旧 iframe 复制的新 iframe:

function setIFrameSrc(idFrame, url) {
    var originalFrame = document.getElementById(idFrame);
    var newFrame = document.createElement("iframe");
    newFrame.id = originalFrame.getAttribute("id");
    newFrame.width = originalFrame.getAttribute("width");
    newFrame.height = originalFrame.getAttribute("height");
    newFrame.src = url;    
    var parent = originalFrame.parentNode;
    parent.replaceChild(newFrame, originalFrame);
}

像这样使用它:

setIFrameSrc("idframe", "test.html");

这种方式不会将 iframe 的 URL 添加到浏览器历史记录中。


1
投票

使用

replace
方法绕过将 iframe 的 URL 添加到历史记录中:

HTML:

<iframe id="myIframe" width="100%" height="400" src="#"></iframe>

JavaScript:

var ifr = document.getElementById('mIframe')
if (ifr) {
  ifr.contentWindow.location.replace('http://www.blabla.com')
}

1
投票

JDandChips 答案在跨源 iframe(youtube)上为我工作,这里是 vanilla JS(没有 JQuery):

const container = iframe.parentElement;

container.removeChild(iframe);

iframe.setAttribute('src', 'about:blank');

container.appendChild(iframe);

0
投票

最简单快速的加载方案
使用

window.location.replace
可以在加载页面或框架时不更新历史记录。

对于链接,它看起来像这样:

<a href="#" onclick="YourTarget.location.replace ('http://www.YourPage.com');">
The targeted Link</a>

<a href="javascript:YourTarget.location.replace ('http://www.YourPage.com');">
The targeted Link</a>



但是如果您希望它不从链接执行而是在加载框架时自动执行,那么您应该将其放在 iframe 文件主体部分中:

onload="window.location.replace ('http://www.YourPage.com');"


如果由于某种原因 onload 未在 iframe 中加载,则将目标框架名称而不是窗口放入语法中,如下所示:

onload="YourTarget.location.replace ('http://www.YourPage.com');"



注意: 对于此脚本,所有

onclick
onmouseover
onmouseout
onload
href="javascript:"
都可以工作。


0
投票

@JDandChips 上面有一个很好的答案,但语法应该从 parent() 更新为 parentElement:

var container = iframe.parentElement;

iframe.remove();
iframe.attr('src', 'about:blank');

container.append(iframe);

0
投票

还有一个很好的解决方案,通过设置

key
iframe
属性来防止 iframe 添加到历史记录中。

特别是如果使用像...这样的框架

反应

<iframe key={contentId} src={`embedded/content/${contentId}`} />

vue

<iframe :key="contentId" :src="src" />

可以在这里找到非常详细的解释:

https://www.aleksandrhovhannisyan.com/blog/react-iframes-back-navigation-bug/

© www.soinside.com 2019 - 2024. All rights reserved.