jQuery。已经在一个dynamic插入的iframe中
当有人点击图片时,我们使用jQuery thickboxdynamic显示iframe。 在这个iframe中,我们使用一个JavaScript库来展示多个图片。
问题似乎是,iframe中的$(document).ready
好像已经被触发了,并且iframe的内容还没有被加载,所以galleria代码没有在DOM元素上正确应用。 $(document).ready
似乎使用iframe父级就绪状态来决定iframe是否准备就绪。
如果我们在一个单独的函数中提取由文档调用的函数,并在100 ms超时后调用它。 它可以工作,但是我们不能借助慢速计算机来抓住生产的机会。
$(document).ready(function() { setTimeout(ApplyGalleria, 100); });
我的问题:我们应该绑定哪个jQuery事件,以便在dynamiciframe准备就绪时执行我们的代码,而不仅仅是父级?
我回答了类似的问题(请参阅IFRAME完成加载时的Javascriptcallback? )。 您可以使用以下代码获取对iframe加载事件的控制权:
function callIframe(url, callback) { $(document.body).append('<IFRAME id="myId" ...>'); $('iframe#myId').attr('src', url); $('iframe#myId').load(function() { callback(this); }); }
在处理iframe时,我发现使用加载事件而不是文档就绪事件足够好。
使用jQuery 1.3.2以下为我工作:
$('iframe').ready(function() { $('body', $('iframe').contents()).html('Hello World!'); });
修订:! 其实上面的代码有时看起来像在Firefox中工作,从来不看起来像在Opera中的作品。
相反,我为我的目的实施了一个投票解决scheme。 简化下来看起来像这样:
$(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>
这大部分时间对我来说都是工作的。 有时候,最简单和最天真的解决scheme是最合适的。
按照DrJokepu和David Murdoch的想法,我实现了一个更完整的版本。 它需要父母和iframe上的jQuery和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"); }); }); }
家长testing代码:
$(function(){ $("iframe").on("iframeloading iframeready iframeloaded iframebeforeunload iframeunloaded", function(e){ console.log(e.type); }); });
find解决问题的办法。
当您点击打开iframe的thickbox链接时,会插入一个ID为TB_iframeContent的iframe。
而不是依靠iframe代码中的$(document).ready
事件,我只需要绑定到父文档中的iframe加载事件:
$('#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>
所有你需要做的就是创buildJavaScript函数testframe_loaded()。
我使用jQuery ajax将PDF加载到浏览器caching中。 然后我用浏览器caching中的数据创buildembedded式元素。 我想这也适用于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');
这是我与客户碰到的确切问题。 我创build了一个jQuery插件,似乎为iframe准备工作。 它使用轮询来检查iframe文档readyState与内部文档url结合iframe源,以确保iframe实际上“准备就绪”。
“onload”的问题是你需要访问被添加到DOM的实际的iframe,如果你不这样做,那么你需要尝试捕获iframe加载,如果它被caching,那么你可能不会。 我需要的是一个可以随时调用的脚本,并确定iframe是否“准备就绪”。
这是一个问题:
确定本地iframe是否已加载的圣杯
这是我最终提出的jsfiddle。
https://jsfiddle.net/q0smjkh5/10/
在上面的jsfiddle中,我正在等待onload将iframe添加到dom,然后检查iframe的内部文档的就绪状态 – 哪个应该跨域,因为它指向维基百科 – 但Chrome似乎报告“完整”。 当iframe实际上准备就绪时,插件的iready方法就会被调用。 callback试图再次检查内部文档的就绪状态 – 这次报告一个跨域请求(这是正确的) – 无论如何,它似乎工作,我需要什么,希望它可以帮助别人。
<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>