在iframe.contentDocument上使用时,jQuery.ready()是否有效?

时间:2011-05-03 13:21:43

标签: javascript jquery iframe document-ready

简单问题(如标题所述): 在jQuery.ready()上使用时,iframe.contentDocument是否有效?

复杂的问题:

我必须在CMS的输入字段上挂钩一个keyup事件,因此我无法控制HTML,只能控制脚本。

输入位于嵌套在另一个iframe中的iframe内,因此有一个顶部窗口(浏览器窗口),一个iframe(让我们称之为iframe1)和另一个iframe(我们称之为iframe2)。脚本和jQuery位于顶部窗口的<head>部分。

我不是很喜欢setTimeout/setInterval,所以我最初的想法就是像这样使用jQuery.ready()(我省略了选择iframe的代码):

$(document).ready(function(){
  $(iframe1.contentDocument).ready(function(){
    $(iframe2.contentDocument).ready(function(){
      $("input").keyup(function(){ /* Do stuff */ });
    });
  });
});

问题是,当.ready()触发iframe1时,我可以检查iframe1.contentDocument.body.innerHTML,结果是一个空字符串。不是人们所期望的。由于这个原因,代码无法绑定keyup事件。

如果有人在想“您使用的是正确的选择器上下文吗?”:是的,我在正确的文档中选择iframe元素(虽然上面的代码片段可能无法完全解释这个,因为我想保持简单)。也没有任何相同的原始政策问题 - 所有iframe和父窗口都在同一个域中。

使用$(window).load()似乎有效,但是等待加载图像等等待的时间太长,而不是应用程序无法接受的。

是否可以在不使用jQuery.ready()的情况下获得可用于iframe的jQuery.load()功能?

3 个答案:

答案 0 :(得分:1)

我不确定您是否反对使用$(window).load(),但您可以将load()直接绑定到iframe并尽可能接近,而无需直接访问添加jquery iframe内容。

我过去做过类似的事情,根据内容的高度动态调整iframe的大小。这是一个可能没有直接关联的例子,但你应该能够得到它正在做的事情的要点。

    $(function(){
    var $content_iframe = $('#content_iframe')

    $content_iframe.load(
        function(){
            var contentHeight = $content_iframe.contents().find('html body').height();
            if (contentHeight > 1070){
                $(this).height(contentHeight + 30);
            }
            else{
                $(this).height(1100);
            }
        }
    );
})

就图像加载时间而言,这可能有同样的缺点。祝你好运!

答案 1 :(得分:1)

刚刚注意到我从未接受过这个答案。

简短回答:不。

答案很长:

一旦jQuery认为DOM已准备好并且触发绑定到ready事件的事件处理程序,jQuery.isReady将设置为true。它(在其他一些事情中)检查document.body是否定义了重复setTimeout(),直到它被定义,但仅限于定义jQuery的窗口。换句话说,它不适用于(i)帧。

来自当前版本的jQuery(1.8.0)的现成代码:

// Handle when the DOM is ready
ready: function( wait ) {

    // Abort if there are pending holds or we're already ready
    if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
        return;
    }

    // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
    if ( !document.body ) {
        return setTimeout( jQuery.ready, 1 );
    }

    // Remember that the DOM is ready
    jQuery.isReady = true;

    // If a normal DOM Ready event fired, decrement, and wait if need be
    if ( wait !== true && --jQuery.readyWait > 0 ) {
        return;
    }

    // If there are functions bound, to execute
    readyList.resolveWith( document, [ jQuery ] );

    // Trigger any bound ready events
    if ( jQuery.fn.trigger ) {
        jQuery( document ).trigger("ready").off("ready");
    }
},

答案 2 :(得分:0)

如果您可以控制加载到<iframe>框中的页面,他们也可以加载自己的jQuery副本并拥有自己的“.ready()”处理程序。反过来,这些处理程序可以与“顶部”页面的JavaScript代码(可能通过jQuery“Deferred”对象)进行通信,这样当所有iframe变为“准备好”时,可以将外部页面设置为运行代码。 / p>

您希望在状态之前设置父页面代码,因为您不确定父页面是否会在子项{{1}之前准备就绪页面。