이것이 내가 고객과 마주 친 정확한 문제였습니다. iframe 준비를 위해 작동하는 것 같은 작은 jquery 플러그인을 만들었습니다. 폴링을 사용하여 iframe 소스와 결합 된 내부 문서 URL과 결합 된 iframe 문서 readyState를 확인하여 iframe이 실제로 "준비"되어 있는지 확인합니다.
"onload"의 문제는 DOM에 추가되는 실제 iframe에 액세스해야한다는 것입니다. 그렇지 않으면 캐시 된 경우 iframe 로딩을 잡아야합니다. 내가 필요한 것은 언제든지 호출 할 수있는 스크립트였으며 iframe이 "준비"되었는지 여부를 결정했습니다.
질문은 다음과 같습니다.
로컬 iframe의로드 여부를 결정하는 성배
그리고 여기에 결국 jsfiddle이 있습니다.
https://jsfiddle.net/q0smjkh5/10/
위의 jsfiddle에서 onload가 dom에 iframe을 추가 할 때까지 기다리고 있습니다 .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>