Este fue el problema exacto con el que me encontré con nuestro cliente. Creé un pequeño complemento jquery que parece funcionar para la preparación de iframe. Utiliza el sondeo para verificar el documento iframe readyState combinado con la url interna del documento combinada con la fuente del iframe para asegurarse de que el iframe esté "listo".
El problema con "onload" es que necesita acceso al iframe real que se agrega al DOM; si no lo hace, debe intentar atrapar la carga del iframe, que si está en caché, entonces no puede. Lo que necesitaba era un script que pudiera llamarse en cualquier momento, y determinar si el iframe estaba "listo" o no.
Aquí está la pregunta:
Santo Grial para determinar si el iframe local se ha cargado o no
y aquí está el jsfiddle que eventualmente se me ocurrió.
https://jsfiddle.net/q0smjkh5/10/
En el jsfiddle anterior, estoy esperando que onload agregue un iframe al dom, luego verifico el estado listo del documento interno del iframe, que debería ser dominio cruzado porque apunta a wikipedia, pero Chrome parece informar "completo". El método iready del complemento se llama cuando el iframe está listo. La devolución de llamada intenta verificar el estado listo del documento interno nuevamente, esta vez informando una solicitud de dominio cruzado (que es correcta), de todos modos parece funcionar para lo que necesito y espero que ayude a otros.
<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>