为什么iframe.contentWindow==为null

Why is iframe.contentWindow == null?

本文关键字:null contentWindow iframe 为什么      更新时间:2023-09-26

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

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

然后,我想访问它的contentWindow,但它为空:

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
});

同样的结果。

怎么了

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

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

所以试试这个:

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

希望这能帮助

问题是,在<iframe>真正添加到页面的实际DOM中之前,它不会是"真实的"。这里有一把小提琴要示范。。

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

下面是一个如何处理它的例子:

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

您还可以通过设置iframe的onload属性来创建一个函数,该函数将在iframe完成加载后执行。

书签版本

只是出于好奇,我想我应该把这些放在一起。请记住,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本身内部触发加载事件要好得多。但这意味着要在iframe中加载一个合适的文档,因此对于动态iframe来说,这有点乏味。这是加载文档和不加载文档的混合。

以上内容适用于我迄今为止测试的所有内容——是的,你是正确的——这有点荒谬,不符合未来,而且可能还有其他负面含义;)

关于这篇文章,我要说的一件积极的事情是,它介绍了使用.contents()来访问iframe的文档,这至少有点有用。。。

值得指出的是,只有当iframe与您的代码具有相同的来源时,该属性才可用;否则,由于浏览器的安全策略,它是null

https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/contentDocument