Questo è stato il problema esatto che ho riscontrato con il nostro cliente. Ho creato un piccolo plugin jquery che sembra funzionare per la prontezza di iframe. Utilizza il polling per verificare il documento iframe readyState combinato con l'URL del documento interno combinato con l'origine iframe per assicurarsi che l'iframe sia effettivamente "pronto".
Il problema con "onload" è che è necessario accedere all'iframe effettivo che viene aggiunto al DOM, in caso contrario è necessario provare a rilevare il caricamento dell'iframe che, se viene memorizzato nella cache, potrebbe non essere possibile. Ciò di cui avevo bisogno era uno script che potesse essere chiamato in qualsiasi momento e determinare se l'iframe fosse "pronto" oppure no.
Ecco la domanda:
Sacro Graal per determinare se iframe locale è stato caricato o meno
ed ecco il jsfiddle che alla fine mi è venuto in mente.
https://jsfiddle.net/q0smjkh5/10/
Nella jsfiddle sopra, sto aspettando che onload aggiunga un iframe al dom, quindi controllo lo stato pronto del documento interno di iframe - che dovrebbe essere interdominio perché è indicato su Wikipedia - ma Chrome sembra riportare "completo". Il metodo iready del plug-in viene quindi chiamato quando l'iframe è effettivamente pronto. Il callback tenta di controllare di nuovo lo stato pronto del documento interno - questa volta riportando una richiesta tra domini (che è corretta) - comunque sembra funzionare per quello di cui ho bisogno e spero che aiuti gli altri.
<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>