为什么iframe.contentWindow == null?

时间:2012-08-30 14:58:21

标签: javascript html dom iframe

我使用以下代码动态创建iframe。

var iframe_jquery = $("<iframe>")
    .addClass("foo")
    .appendTo(container); // container is a jQuery object containing a <div> which already exists

然后,我想访问它的contentWindow,但它是null:

var iframe = iframe_jquery.get(0);
if (iframe){ // iFrame exists
    console.log(iframe.contentWindow); // Prints "null"
    var doc = iframe.contentWindow.document; // NullpointerException
}

所以我想:“也许iframe尚未准备好了吗?”所以我试过了:

iframe_jquery.ready(function(){
    var iframe = iframe_jquery.get(0);
    console.log(iframe.contentWindow); // Prints "null"
    var doc = iframe.contentWindow.document; // NullpointerException
});

同样的结果。

怎么了?

5 个答案:

答案 0 :(得分:34)

上周我在使用iFrames(构建rtf编辑器)时遇到了这个问题,是的还没有准备好。

我想如果我把它放在.ready()它会起作用,但是.ready()是DOM准备好的时候,而不是当iFrame加载了它的内容时,所以我最终用我的代码包装jQuery .load()

所以试试这个:

$(function () {  
    $("#myiframe").load(function () {                        
        frames["myframe"].document.body.innerHTML = htmlValue;
    });
}); 

希望这有帮助

答案 1 :(得分:14)

问题是你的<iframe>在真正添加到页面的实际DOM之前不会是“真实的”。 Here is a fiddle to demonstrate.

答案 2 :(得分:6)

根据浏览器的不同,访问document<iframe>可能会有所不同。

以下是如何处理它的示例:

if (iframe.contentDocument) // FF Chrome
  doc = iframe.contentDocument;
else if ( iframe.contentWindow ) // IE
  doc = iframe.contentWindow.document;

答案 3 :(得分:2)

Bookmarklet版本

出于好奇,我以为我会把它放在一起。记住iframe和加载事件在不同的浏览器(主要是较旧的,分崩离析的,应该是死的浏览器)上不能很好地协同工作 ...而且还不能完全确定jQuery是如何解决这个问题的......我的大脑决定更好地支持(无论是否在这里也不存在)

$(function(){
  /// bind a listener for the bespoke iframeload event
  $(window).bind('iframeload', function(){
    /// access the contents of the iframe using jQuery notation
    iframe.show().contents().find('body').html('hello');
  });
  /// create your iframe
  var iframe = $('<iframe />')
        /// by forcing our iframe to evaluate javascript in the path, we know when it's ready
        .attr('src', 'javascript:(function(){try{p=window.parent;p.jQuery(p).trigger(\'iframeload\');}catch(ee){};})();')
        /// insert the iframe into the live DOM
        .appendTo('body');
});

采用这种方法的原因是,从iframe内部触发load事件通常要好得多。但这意味着将一个适当的文档加载到iframe中,因此对于动态iframe,这有点单调乏味。这是加载文档之间的混合,而不是。

以上对我到目前为止所测试的所有内容都有效 - 是的,你是对的 - 它有点荒谬,不具备未来性,可能还有其他具有负面含义的东西;)

我要对这篇文章说一个积极的事情是介绍使用.contents()来访问iframe的文档,这至少有点用处......

答案 4 :(得分:1)

你也可以通过设置ifload属性来制作一个在iframe完成加载时执行的功能。