简体   繁体   English

在IE中访问友好的iframe内容

[英]Accessing friendly iframe contents in IE

I've created a friendly iframe (same domain) and added it to the DOM with JavaScript. 我创建了一个友好的iframe (相同的域),并使用JavaScript将其添加到DOM中。 It's visible on my page. 在我的页面上可见。 Inspecting the HTML looks like: 检查HTML看起来像:

<iframe id="test_frame" frameSpacing="0" height="100" src="javascript:window['contents']" width="100" name="test_frame">
  <!DOCTYPE html>
  <html>
    <head>
      <title>test_frame</title>
      <base target=_top>
    </head>
    <body style="margin: 0px; padding: 0px">
      <p>Hello World</p>
    </body>
  </html>
</iframe>

Then I run the following in order to access the markup in the iframe's <body> : 然后,我运行以下命令以访问iframe的<body>的标记:

    alert(window.frames["test_frame"].document.body.innerHTML);

which fails for Internet Explorer 6-10 because body is null . 由于bodynull因此对于Internet Explorer 6-10失败 The document object of the iframe exists, but appears to have no readable properties. iframe的document对象存在,但似乎没有可读属性。 Other browsers simply display the string <p>Hello World</p> . 其他浏览器仅显示字符串<p>Hello World</p>

But interestingly, the following works in IE 6-10, and all other browsers: 但有趣的是,以下内容可在IE 6-10和所有其他浏览器中使用:

    window.setTimeout(function(){
      alert(window.frames["test_frame"].document.body.innerHTML);
    }, 1);

To my knowledge setTimeout executes the passed function in the global scope. 据我所知, setTimeout在全局范围内执行传递的函数。 So I tried using call but it does not work: 于是,我就用电话 ,但它工作:

    (function(){
      alert(window.frames["test_frame"].document.body.innerHTML);
    }).call(window);

I have seen similar cases where wrapping code in a setTimeout resolves IE iframe difficulties. 我看到过类似的情况,其中将代码包装在setTimeout中可以解决IE iframe的难题。 What is the mechanism or logic behind this in IE? IE中背后的机制或逻辑是什么? Is there a proper workaround? 有适当的解决方法吗?

Above tests were run in standards mode, with no other errors than those stated. 以上测试均以标准模式运行,除规定的错误外,没有其他错误。

What is the mechanism or logic behind this in IE? IE中背后的机制或逻辑是什么? Is there a proper workaround? 有适当的解决方法吗?

The mechanism is very simple: wait one milisecond (four; actually), then attempt to access the iFrame. 该机制非常简单:等待一毫秒(实际上是四个),然后尝试访问iFrame。

Timing is everything. 时间就是一切。 If you call too soon, you will see an empty iFrame. 如果致电太早,您会看到一个空的iFrame。 Even if the src is javascript code, you have to let the code run. 即使src是javascript代码,也必须让代码运行。


  • If you access the iFrame just after it is encountered in the DOM: most likely it will be empty. 如果您在DOM中遇到iFrame后立即访问它:最有可能为空。 It has not been fetched from the Internet yet. 尚未从Internet上获取它。 Even if the src is javascript:... , the iFrame will be empty . 即使srcjavascript:... ,iFrame也会为空

  • If you do it 1 millisecond after the page load, most likely it has not been fetched yet either. 如果您在页面加载后的1毫秒内执行此操作,则很可能还没有获取它。 However, if it's in the browser cache (normally a page shouldn't be) or it's a data (or javascript, in your case) URL, however, this will likely work (nothing's granted, though). 但是,如果它位于浏览器缓存中(通常不应该存在页面),或者它是数据(或JavaScript,在您的情况下)URL,则此方法可能会起作用(尽管没有任何结果)。 The document.body element may already exist at this point - even if it's going to be empty. 此时document.body元素可能已经存在-即使它为空。

  • The intended workflow is that you wait for the iFrame load event. 预期的工作流程是您等待iFrame load事件。 You can safely attach it just after you create the iFrame or set its src . 您可以在创建iFrame或设置其src之后安全地附加它。 Finding a cross-browser set of events that messages this reliably is a tricky issue, but load should work cross-browser. 找到一个跨浏览器事件集以可靠地向其发送消息是一个棘手的问题,但是load应该跨浏览器工作。

  • If the load event fails to be late enough, wait an extra millisecond. 如果load事件未能足够迟,请再等待一毫秒。 This should not be neccessary, but there might be a stupid bug in IE (I don't think there is). 这不是必须的,但是IE中可能存在一个愚蠢的错误(我认为没有)。

  • It you are firing it from the console, this should be successful. 如果您从控制台启动它,则应该成功。 Indeed, this has always been the case according to my observation. 实际上,根据我的观察,情况一直如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM