从单独的 iframe 重新加载 iframe

4
我已查看了stackoverflow上所有关于从另一个iframe重新加载iframe的帖子,并尝试了它们所有的解决方案,但似乎都没能帮助我!我的问题是,我在同一页上有两个iframes。这两个iframe的源是互相交互的php文件,然而我需要重新加载iframes以便显示更改。我尝试了许多不同的方法(我将在下面列出)。这些iframes来自同一域。也许是其他东西搞砸了吗?提前感谢您的帮助。
从一个iframe内调用的不同语句:
parent.document.getElementById(id).src = parent.document.getElementById(id).src;
parent.getElementById(id).location.reload();

尝试调用在父窗口中有效的父函数:
在iframe内部 -
parent.refresh(id);

父窗口工作功能 -

function refresh(id) {
document.getElementById(id).src = document.getElementById(id).src;
}

两个 iframe 是否来自于你的 PHP 脚本相同的域名?如果不是,你无法修改其他域名的 iframe。 - Skarlinski
是的,它们是。抱歉我忘记包括那个了。 - Spencer May
在第一个 iframe 完成后,如果您手动从控制台运行 refresh("idString"),会发生什么? - Skarlinski
还有,iframe 是否可能是嵌套的?比如一个 iframe 在另一个 iframe 中? - Skarlinski
refresh(id)函数在从父窗口运行时能够刷新iframe,但在从子iframe运行时却无法刷新。 - Spencer May
你能发布一下显示 iframe 元素的标记吗? - nothingisnecessary
1个回答

11
如果您将一个名称name分配给iframe,大多数浏览器将允许您通过name值访问iframewindow对象。这与通过id属性引用iframe不同,后者将为您提供对iframe元素本身(从其所有者document)的引用,而不是iframe内容的window
简单示例:(来自父文档)
<iframe name='iframe1Name' id='iframe1Id'></iframe>
<script>
    // option 1: get a reference to the iframe element:
    var iframeElem = document.getElementById('iframe1Id');

    // update the element's src:
    iframeElem.src = "page.html";

    // option 2: get a reference to the iframe's window object:
    var iframeWindow = window.iframe1Name;    

    // update the iframe's location:
    iframeWindow.location.href = "page.html";
</script>

让我们来审查你的代码:

parent.document.getElementById(id).src = parent.document.getElementById(id).src;

如果在iframe中执行并使用正确的id,那么这将起作用。您可能需要使用调试器来验证parent.document.getElementById(id)返回对正确元素的引用,并检查您的控制台以查看是否抛出任何异常(尝试按F12)。由于您没有发布完整的代码(包括标记),因此我无法想到如何告诉您问题所在。

调试提示:

  • 检查parent.location.href以确保您正在访问您认为的窗口,
  • 检查parent.document.getElementId(id)以确保您获取一个元素对象(而不是nullundefined),
  • 检查parent.document.getElementById(id).tagName以确保您正在使用正确的ID(tagName应为 "IFRAME")

这行代码:

parent.getElementById(id).location.reload();

有两个问题:

  1. getElementById()document 的一个函数,但它正在从 parent (一个 window 对象) 调用,
  2. location 是一个 window 对象的属性。你正在尝试访问 iframe 元素的 location 属性,但它不存在。你需要引用 iframewindow,而不是它的元素。

除了使用 name 方法外,还有其他获取 iframe 窗口对象的方法:

  1. document.getElementById('iframeId').contentWindow; // 适用于支持的浏览器
  2. window.frames["iframeName"]; // 假设 iframe 的 name 属性已设置
  3. window.frames[i]; // i 是 frame 的序号

如果更改 iframe 元素的 src 属性对你没有用,请尝试以下解决方法:

parent.document.getElementById(id).contentWindow.location.reload();

或者

parent.frames["yourIframeName"].location.reload(); // 需要 iframe 的 name 属性

或者

parent.frames[0].location.reload(); // 立即父窗口的 frames

或者

top.frames[0].location.reload(); // 最顶层父窗口的 frames

注意:如果使用 name 方法,请不要使用常见值作为 name,比如 "home",因为它与 Firefox 的一个名为 home() 的函数冲突。因此,如果一个 iframe 命名为 home,Firefox 将不会自动创建对其窗口的引用。最可靠的方法可能是使用 window.frames[],因为我相信它已经存在很长时间了(在 Firefox / Chrome / Safari / IE6+ (至少) 中可用)。

下面是一个更详细(但很简单)的示例,在 Chrome、Firefox 和 IE 中进行了测试:

文件 #1:frametest.html(父窗口)

<!DOCTYPE html>
<html>
<body>
    <iframe id="frame1Id" name="frame1Name" src="frame1.html"></iframe>
    <iframe id="frame2Id" name="frame2Name" src="frame2.html"></iframe>
</body>
</html>

文件#2: frame1.html(frame 1的src)

<!DOCTYPE html>
<html>
<body>
FRAME 1
<script>
    document.body.style.backgroundColor="#ccc";
    setTimeout(function(){document.body.style.backgroundColor="#fff";},100);
    document.write(new Date());
</script>
<input type="button" onclick="parent.document.getElementById('frame2Id').src=parent.document.getElementById('frame2Id').src;" value="Refresh frame 2 by ID"/>
<input type="button" onclick="parent.frame2Name.location.reload();" value="Refresh frame 2 by Name"/>
</body>
</html>

文件 #3:frame2.html(frame 2的src)

<!DOCTYPE html>
<html>
<body>
FRAME 1
<script>
    document.body.style.backgroundColor="#ccc";
    setTimeout(function(){document.body.style.backgroundColor="#fff";},100);
    document.write(new Date());
</script>
<input type="button" onclick="parent.document.getElementById('frame1Id').src=parent.document.getElementById('frame1Id').src;" value="Refresh frame 2 by ID"/>
<input type="button" onclick="parent.frame1Name.location.reload();" value="Refresh frame 2 by Name"/>
</body>
</html>

这个示例演示了如何通过idname定义和操作iframe,以及如何从一个不同的iframe中影响一个iframe。根据浏览器设置,可能会应用起源策略,但你已经说过你的内容都来自同一域,所以在那方面你应该没问题。


这绝对是一篇非常有用的文章!它帮助我解决了我的问题,并让我学到了不少知识。谢谢 :) - Spencer May

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接