Ini adalah masalah persis yang saya temui dengan klien kami. Saya membuat plugin jquery kecil yang tampaknya berfungsi untuk kesiapan iframe. Menggunakan polling untuk memeriksa dokumen iframe readyState yang dikombinasikan dengan url dokumen bagian dalam yang dikombinasikan dengan sumber iframe untuk memastikan iframe sebenarnya "siap".
Masalah dengan "onload" adalah bahwa Anda memerlukan akses ke iframe aktual yang ditambahkan ke DOM, jika Anda tidak maka Anda perlu mencoba untuk menangkap pemuatan iframe yang jika di-cache maka Anda mungkin tidak. Yang saya butuhkan adalah skrip yang bisa dipanggil kapan saja, dan menentukan apakah iframe itu "siap" atau tidak.
Inilah pertanyaannya:
Cawan suci untuk menentukan apakah iframe lokal telah dimuat atau tidak
dan inilah jsfiddle yang akhirnya kutemukan.
https://jsfiddle.net/q0smjkh5/10/
Dalam jsfiddle di atas, saya menunggu onload untuk menambahkan iframe ke dom, kemudian memeriksa status ready dokumen dalam iframe - yang harus lintas domain karena itu menunjuk ke wikipedia - tetapi Chrome tampaknya melaporkan "lengkap". Metode iready plug-in kemudian dipanggil ketika iframe sebenarnya sudah siap. Callback mencoba untuk memeriksa status siap dokumen dalam lagi - kali ini melaporkan permintaan lintas domain (yang benar) - bagaimanapun tampaknya berfungsi untuk apa yang saya butuhkan dan berharap itu membantu orang lain.
<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>