如果在iframe加载完成后附加了$('#someIframe').load(function(){...}),那么它似乎不会触发。对吗?
我真正想要的是有一个函数,它总是在加载iframe时或之后调用一次。为了让这一点更清楚,这里有两个案例:
我该怎么做呢?
发布于 2016-03-22 21:23:14
我一直把头撞在墙上,直到弄清楚这里发生了什么。
背景信息
如果已经加载了iframe,则使用.load()的
.ready()的postMessage或在iframe内的load上调用容器函数的$(window).load()的readyState,这不是一个解决方案,因为一个alredy触发的onload事件是没有意义的,因为Chrome会用一个“about:空白”的空白页面初始化每个iframe。此页的readyState可能是complete,但它不是您期望的页的readyState (src属性)。解决方案
以下内容是必需的:
如果iframe还没有加载,我们可以观察到iframe的事件。如果iframe已经加载,我们需要检查readyState
readyState is complete,我们通常可以假定iframe已经加载。然而,由于Chrome的上述行为,我们还需要检查它是否是空页面的readyState readyState,以检查实际文档(与src属性相关)是否为Chrome我已经用下面的函数解决了这个问题。它已经(转译为ES5)在
取自 的函数
/**
* Will wait for an iframe to be ready
* for DOM manipulation. Just listening for
* the load event will only work if the iframe
* is not already loaded. If so, it is necessary
* to observe the readyState. The issue here is
* that Chrome will initialize iframes with
* "about:blank" and set its readyState to complete.
* So it is furthermore necessary to check if it's
* the readyState of the target document property.
* Errors that may occur when trying to access the iframe
* (Same-Origin-Policy) will be catched and the error
* function will be called.
* @param {jquery} $i - The jQuery iframe element
* @param {function} successFn - The callback on success. Will
* receive the jQuery contents of the iframe as a parameter
* @param {function} errorFn - The callback on error
*/
var onIframeReady = function($i, successFn, errorFn) {
try {
const iCon = $i.first()[0].contentWindow,
bl = "about:blank",
compl = "complete";
const callCallback = () => {
try {
const $con = $i.contents();
if($con.length === 0) { // https://git.io/vV8yU
throw new Error("iframe inaccessible");
}
successFn($con);
} catch(e) { // accessing contents failed
errorFn();
}
};
const observeOnload = () => {
$i.on("load.jqueryMark", () => {
try {
const src = $i.attr("src").trim(),
href = iCon.location.href;
if(href !== bl || src === bl || src === "") {
$i.off("load.jqueryMark");
callCallback();
}
} catch(e) {
errorFn();
}
});
};
if(iCon.document.readyState === compl) {
const src = $i.attr("src").trim(),
href = iCon.location.href;
if(href === bl && src !== bl && src !== "") {
observeOnload();
} else {
callCallback();
}
} else {
observeOnload();
}
} catch(e) { // accessing contentWindow failed
errorFn();
}
};工作示例
由两个文件(index.html和iframe.html)组成:index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Parent</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-1.12.2.min.js"></script>
<script>
$(function() {
/**
* Will wait for an iframe to be ready
* for DOM manipulation. Just listening for
* the load event will only work if the iframe
* is not already loaded. If so, it is necessary
* to observe the readyState. The issue here is
* that Chrome will initialize iframes with
* "about:blank" and set its readyState to complete.
* So it is furthermore necessary to check if it's
* the readyState of the target document property.
* Errors that may occur when trying to access the iframe
* (Same-Origin-Policy) will be catched and the error
* function will be called.
* @param {jquery} $i - The jQuery iframe element
* @param {function} successFn - The callback on success. Will
* receive the jQuery contents of the iframe as a parameter
* @param {function} errorFn - The callback on error
*/
var onIframeReady = function($i, successFn, errorFn) {
try {
const iCon = $i.first()[0].contentWindow,
bl = "about:blank",
compl = "complete";
const callCallback = () => {
try {
const $con = $i.contents();
if($con.length === 0) { // https://git.io/vV8yU
throw new Error("iframe inaccessible");
}
successFn($con);
} catch(e) { // accessing contents failed
errorFn();
}
};
const observeOnload = () => {
$i.on("load.jqueryMark", () => {
try {
const src = $i.attr("src").trim(),
href = iCon.location.href;
if(href !== bl || src === bl || src === "") {
$i.off("load.jqueryMark");
callCallback();
}
} catch(e) {
errorFn();
}
});
};
if(iCon.document.readyState === compl) {
const src = $i.attr("src").trim(),
href = iCon.location.href;
if(href === bl && src !== bl && src !== "") {
observeOnload();
} else {
callCallback();
}
} else {
observeOnload();
}
} catch(e) { // accessing contentWindow failed
errorFn();
}
};
var $iframe = $("iframe");
onIframeReady($iframe, function($contents) {
console.log("Ready to got");
console.log($contents.find("*"));
}, function() {
console.log("Can not access iframe");
});
});
</script>
<iframe src="iframe.html"></iframe>
</body>
</html>iframe.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Child</title>
</head>
<body>
<p>Lorem ipsum</p>
</body>
</html>您还可以将index.html中的src属性更改为例如"http://example.com/“。玩它就好了。
发布于 2013-06-18 15:29:52
我会使用postMessage。iframe可以将它自己的onload事件和post分配给父对象。如果存在计时问题,只需确保在创建iframe之前分配父进程的postMessage处理程序。
为此,iframe必须知道父元素的url,例如通过向iframe传递GET参数。
发布于 2019-01-28 17:46:12
我也有同样的问题。在我的例子中,我只是简单地检查了onload函数是否被触发。
var iframe = document.getElementById("someIframe");
var loadingStatus = true;
iframe.onload = function () {
loadingStatus = false;
//do whatever you want [in my case I wants to trigger postMessage]
};
if (loadingStatus)
//do whatever you want [in my case I wants to trigger postMessage]https://stackoverflow.com/questions/17158932
复制相似问题