我们正在使用jQuery thickbox 在有人点击图片时动态显示iframe。在这个iframe中,我们使用 galleria 一个javascript库来显示多张图片。

问题似乎是iframe中的 $(document).ready 似乎太快被解雇了,iframe内容甚至还没有加载,所以galleria代码没有正确应用DOM元素。 $(document).ready 似乎使用iframe父级就绪状态来判断iframe是否准备就绪。

如果我们在单独的函数中提取文档就绪所调用的函数,并在超时100毫秒后调用它。它有效,但我们不能利用慢速计算机进行生产。

$(document).ready(function() { setTimeout(ApplyGalleria, 100); });

我的问题:我们应该绑定哪个jQuery事件,以便在动态iframe准备就绪时能够执行我们的代码,而不仅仅是它的父级?

有帮助吗?

解决方案

我回答了类似的问题(请参阅 IFRAME完成加载时的Javascript回调? )。 您可以使用以下代码控制iframe加载事件:

function callIframe(url, callback) {
    $(document.body).append('<IFRAME id="myId" ...>');
    $('iframe#myId').attr('src', url);

    $('iframe#myId').load(function() {
        callback(this);
    });
}

在处理iframe时,我发现使用load事件而不是文档就绪事件就足够了。

其他提示

使用jQuery 1.3.2,以下对我有用:

$('iframe').ready(function() {
  $('body', $('iframe').contents()).html('Hello World!');
});

REVISION:! 实际上上面的代码看起来有点像在Firefox中工作,看起来它在Opera中看起来没用。

相反,我为我的目的实施了一个轮询解决方案。简化它看起来像这样:

$(function() {
  function manipIframe() {
    el = $('body', $('iframe').contents());
    if (el.length != 1) {
      setTimeout(manipIframe, 100);
      return;
    }
    el.html('Hello World!');
  }
  manipIframe();
});

这不需要调用iframe页面中的代码。所有代码都驻留在父框架/窗口中并执行。

在IFrame中,我通常通过在块的最末端放一个小脚来解决这个问题:

<body>
The content of your IFrame
<script type="text/javascript">
//<![CDATA[
   fireOnReadyEvent();
   parent.IFrameLoaded();
//]]>
</script>
</body>

这项工作大部分时间都适合我。有时最简单,最天真的解决方案是最合适的。

按照约克博士和大卫默多克的想法,我实施了一个更完整的版本。 需要 jQuery,父和iframe以及iframe都在您的控件中。

iframe代码:

var iframe = window.frameElement;

if (iframe){
    iframe.contentDocument = document;//normalization: some browsers don't set the contentDocument, only the contentWindow

    var parent = window.parent;
    $(parent.document).ready(function(){//wait for parent to make sure it has jQuery ready
        var parent$ = parent.jQuery;

        parent$(iframe).trigger("iframeloading");

        $(function(){
            parent$(iframe).trigger("iframeready");
        });

        $(window).load(function(){//kind of unnecessary, but here for completion
            parent$(iframe).trigger("iframeloaded");
        });

        $(window).unload(function(e){//not possible to prevent default
            parent$(iframe).trigger("iframeunloaded");
        });

        $(window).on("beforeunload",function(){
            parent$(iframe).trigger("iframebeforeunload");
        });
    });
}

家长测试代码:

$(function(){
    $("iframe").on("iframeloading iframeready iframeloaded iframebeforeunload iframeunloaded", function(e){
        console.log(e.type);
    });
});

找到问题的解决方案。

当您点击打开iframe的厚盒链接时,会插入一个ID为TB_iframeContent的iframe。

我不必依赖iframe代码中的 $(document).ready 事件,而只需绑定到父文档中iframe的load事件:

$('#TB_iframeContent', top.document).load(ApplyGalleria);

此代码位于iframe中,但绑定到父文档中控件的事件。它适用于FireFox和IE。

试试这个,

<iframe id="testframe" src="about:blank" onload="if (testframe.location.href != 'about:blank') testframe_loaded()"></iframe>

您需要做的就是创建JavaScript函数testframe_loaded()。

我正在将带有jQuery ajax的PDF加载到浏览器缓存中。然后我用浏览器缓存中的数据创建嵌入元素。我想它也适用于iframe。


var url = "http://example.com/my.pdf";
// show spinner
$.mobile.showPageLoadingMsg('b', note, false);
$.ajax({
    url: url,
    cache: true,
    mimeType: 'application/pdf',
    success: function () {
        // display cached data
        $(scroller).append('<embed type="application/pdf" src="' + url + '" />');
        // hide spinner
        $.mobile.hidePageLoadingMsg();
    }
});

您还必须正确设置http标头。


HttpContext.Response.Expires = 1;
HttpContext.Response.Cache.SetNoServerCaching();
HttpContext.Response.Cache.SetAllowResponseInBrowserHistory(false);
HttpContext.Response.CacheControl = "Private";

基本上其他人已发布但恕我直言的更清洁:

$('<iframe/>', {
    src: 'https://example.com/',
    load: function() {
        alert("loaded")
    }
}).appendTo('body');

这是我与客户遇到的确切问题。我创建了一个小jquery插件,似乎适用于iframe准备。它使用轮询来检查iframe文档readyState与内部文档URL结合iframe源以确保iframe实际上是“就绪”。

“onload”的问题是你需要访问添加到DOM的实际iframe,如果你没有,那么你需要尝试捕获iframe加载,如果它被缓存,那么你可能不会。我需要的是一个可以随时调用的脚本,并确定iframe是否已“准备好”。或不。

以下是问题:

确定是否是圣杯本地iframe已加载

这是我最终提出的jsfiddle。

https://jsfiddle.net/q0smjkh5/10/

在上面的jsfiddle中,我正在等待onload将iframe附加到dom,然后检查iframe的内部文档的就绪状态 - 这应该是跨域的,因为它指向维基百科 - 但Chrome似乎报告“完成”。然后在iframe实际就绪时调用插件的iready方法。回调试图再次检查内部文档的就绪状态 - 这次报告跨域请求(这是正确的) - 无论如何它似乎适用于我需要的东西并希望它能帮助其他人。

<script>
  (function($, document, undefined) {
    $.fn["iready"] = function(callback) {
      var ifr = this.filter("iframe"),
          arg = arguments,
          src = this,
          clc = null, // collection
          lng = 50,   // length of time to wait between intervals
          ivl = -1,   // interval id
          chk = function(ifr) {
            try {
              var cnt = ifr.contents(),
                  doc = cnt[0],
                  src = ifr.attr("src"),
                  url = doc.URL;
              switch (doc.readyState) {
                case "complete":
                  if (!src || src === "about:blank") {
                    // we don't care about empty iframes
                    ifr.data("ready", "true");
                  } else if (!url || url === "about:blank") {
                    // empty document still needs loaded
                    ifr.data("ready", undefined);
                  } else {
                    // not an empty iframe and not an empty src
                    // should be loaded
                    ifr.data("ready", true);
                  }

                  break;
                case "interactive":
                  ifr.data("ready", "true");
                  break;
                case "loading":
                default:
                  // still loading
                  break;   
              }
            } catch (ignore) {
              // as far as we're concerned the iframe is ready
              // since we won't be able to access it cross domain
              ifr.data("ready", "true");
            }

            return ifr.data("ready") === "true";
          };

      if (ifr.length) {
        ifr.each(function() {
          if (!$(this).data("ready")) {
            // add to collection
            clc = (clc) ? clc.add($(this)) : $(this);
          }
        });
        if (clc) {
          ivl = setInterval(function() {
            var rd = true;
            clc.each(function() {
              if (!$(this).data("ready")) {
                if (!chk($(this))) {
                  rd = false;
                }
              }
            });

            if (rd) {
              clearInterval(ivl);
              clc = null;
              callback.apply(src, arg);
            }
          }, lng);
        } else {
          clc = null;
          callback.apply(src, arg);
        }
      } else {
        clc = null;
        callback.apply(this, arguments);
      }
      return this;
    };
  }(jQuery, document));
</script>
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top