JavaScript中等待iframe加载

56

我正在JavaScript中打开一个iframe:

righttop.location = "timesheet_notes.php";

然后想要把信息传递给它:

righttop.document.notesform.ID_client.value = Client;
很显然,直到iframe完全加载并且表单元素存在于其中才能使用该行代码。那么,最佳/最有效的解决方法是什么呢?一些超时循环吗?理想情况下,我真的希望将所有内容都包含在这个特定的脚本中,而不必添加任何额外的东西到正在打开的页面中。
5个回答

98

首先,我认为你应该操作iframe的src属性,而不是location。其次,钩子绑定在iframe的load事件上,以执行您的更改:

var myIframe = document.getElementById('righttop');
myIframe.addEventListener("load", function() {
  this.contentWindow.document.notesform.ID_client.value = Client;
});
myIframe.src = 'timesheet_notes.php';

再次说明,这一切都是以您指的iframe为前提,而不是框架集(framesets)。


有没有一种方法可以通过附加事件来实现这个?假设iframe可能有它自己的onload处理程序,我不想通过重新分配onload属性而意外地破坏它们。 - Eric Nguyen
1
@Eric:是的。使用像Mootools、Prototype 1.6或jQuery这样的库。如果你没有其中之一,可以使用这个:http://ejohn.org/blog/flexible-javascript-events/。 - Crescent Fresh
啊...这是不是意味着脚本中触发页面加载的onload函数可能会干扰已加载页面中的onload函数?我猜只要它们不都试图读写同一个元素,那就没问题了吧? - Bill Dawes
@Bill:不,@Eric的问题是关于这个答案是否会干扰设置在<iframe>元素本身上的任何onload="..."属性。对此的答案是肯定的。但是,在iframe文档内设置的任何onload处理程序不受影响。 - Crescent Fresh
很奇怪,我可以使用 <iframe onload=""> 这种方式使它起作用,但无法使用 iframe.onload = function(){}。 - Alper

7
我猜你可以很容易地用jQuery来做到这一点... jQuery主页只需将页面与jQuery的$函数()连接起来即可...例如:
$(document).ready(function() { 
    $('iframe').load(function() { 
       // write your code here....
    });
});

请快速查看这里的文件上传示例:使用iframe实现多文件上传...


3
我其实不想涉及jQuery(还没有打开那扇门),我希望只用几行简洁的JavaScript代码就能解决它。但无论如何,还是谢谢你,Rajesh! - Bill Dawes
没问题,谢谢您的发帖让我学会了一些不使用jQuery的技巧 :) - rajesh pillai
1
对我不起作用 - Nam G VU

2

iFrame可以动态加载元素,与它们一起工作的最佳选项是使用递归:

 $('iframe').ready(function() {
   var triggerMeAgainIfNeeded = function() {
      setTimeout(function() {
          var neededElm = $('.someElementThatLoadedAfterIframe');
           if (neededElm.length > 0) {
             // do your job
           } else {
             triggerMeAgainIfNeeded();
           }
       }, 10);
   }
});

如果使用setTimeout(),我想我们不需要iframe .read(),可以在文档.read()时立即执行。 - Nam G VU
是的,@NamGVU,但如果iframe在文档准备事件之后动态添加,则需要监听iframe。 - rolyanos

1
试试这个简单的解决方案:

const myIframe = document.querySelector('iframe[name="my-iframe"]');
const waitForMyIframeToReload = () => (new Promise(resolve => myIframe.addEventListener('load', () => resolve())));
myIframe.contentWindow.location.reload(true);
await waitForSdiIframeToReload();
console.log('I executed after the iframe loaded'));
<html>
  <body style="height: 100%; width: 100%;">
    <iframe name="my-iframe" src="https://platform.twitter.com/widgets/tweet_button.html" style="height: 100%; width: 100%;"></iframe>
  </body>
</html>


你的回答可以通过提供更多的支持性信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的回答是否正确。你可以在帮助中心找到更多关于如何撰写好回答的信息。 - undefined

0

试试这个...

$('iframe').each(function() { 
    $(this).ready(function() {
        $('#result').html("ready");
    });
});

20
楼主从未提到jQuery,并且帖子中没有jQuery标签。因此,我建议他们并不寻求jQuery答案。 - James Khoury

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