javascript - how - js iframe contentdocument
El evento ''carga'' no se activa cuando el iframe se carga en Chrome (5)
Estoy tratando de mostrar una ''máscara'' en mi cliente mientras un archivo se genera dinámicamente en el servidor. Parece que la recomendación de evitar esto (ya que no es ajax) es utilizar un iframe y escuchar del evento onload o done para determinar cuándo el archivo se ha enviado al cliente desde el servidor.
aquí está mi código angular:
var url = // url to my api
var e = angular.element("<iframe style=''display:none'' src=" + url + "></iframe>");
e.load(function() {
$scope.$apply(function() {
$scope.exporting = false; // this will remove the mask/spinner
});
});
angular.element(''body'').append(e);
Esto funciona muy bien en Firefox pero no tuvo suerte en Chrome. También intenté usar la función de carga:
e.onload = function() { //unmask here }
Pero tampoco tuve suerte allí.
Ideas?
Lamentablemente, no es posible utilizar un evento de onload
de iframe en Chrome si el contenido es un archivo adjunto. Esta answer puede proporcionarle una idea de cómo puede evitarlo.
Me acabo de dar cuenta de que Chrome no siempre activa el evento de carga para la página principal, por lo que esto podría tener un efecto en los iframes, ya que básicamente se tratan de la misma manera.
Use Dev Tools o la API de rendimiento para verificar si el evento de carga se está disparando.
Acabo de comprobar http://ee.co.uk/ y si abre la consola e ingresa window.performance.timing encontrará que las entradas para domComplete, loadEventStart y loadEventEnd son 0 - al menos en este momento actual :)
Parece que hay un problema con Chrome aquí. Lo he comprobado en 2 PC con la última versión 31.0.1650.63.
Actualización: comprobé ee de nuevo y cargué el evento disparado pero no en las recargas posteriores, por lo que esto es intermitente y posiblemente esté relacionado con errores de carga en su sitio. Pero el evento de carga debería disparar lo que sea.
Este problema se ha producido en 5 o 6 sitios ahora en el último día, ya que noté que mi propia supervisión del sitio fallaba ocasionalmente. Solo identifiqué la causa de esto. Necesito un poco de sueño de belleza, luego investigaré más cuando esté más despierto.
Odio esto, pero no pude encontrar otra manera que verificar si todavía se está cargando o no, excepto al verificar a intervalos.
var timer = setInterval(function () {
iframe = document.getElementById(''iframedownload'');
var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
// Check if loading is complete
if (iframeDoc.readyState == ''complete'' || iframeDoc.readyState == ''interactive'') {
loadingOff();
clearInterval(timer);
return;
}
}, 4000);
Puedes hacerlo de otra manera:
En el documento principal:
function iframeLoaded() {
$scope.$apply(function() {
$scope.exporting = false; // this will remove the mask/spinner
});
}
var url = // url to my api
var e = angular.element("<iframe style=''display:none'' src=" + url + "></iframe>");
angular.element(''body'').append(e);
En el documento iframe (esto es, dentro del html de la página referenciada por url)
window.onload = function() {
parent.iframeLoaded();
}
Esto funcionará si la página principal y la página dentro del iframe están en el mismo dominio.
En realidad, puede acceder al padre a través de:
window.parent
parent
//and, if the parent is the top-level document, and not inside another frame
top
window.top
Es más seguro usar window.parent
ya que las variables parent
y top
se pueden sobrescribir (generalmente no se pretende).
debes considerar 2 puntos:
Primero que todo, si su URL tiene un nombre de dominio diferente, no es posible hacer esto, excepto cuando tiene acceso al otro dominio para agregar el encabezado Access-Control-Allow-Origin: *
, para arreglar esto, vaya a este link .
2- pero si tiene el mismo dominio o si ha agregado Access-Control-Allow-Origin: *
a los encabezados de su dominio, puede hacer lo que desee así:
var url = // url to my api
var e = angular.element("<iframe style=''display:none'' src=" + url + "></iframe>");
angular.element(document.body).append(e);
e[0].contentWindow.onload = function() {
$scope.$apply(function() {
$scope.exporting = false; // this will remove the mask/spinner
});
};
Lo he hecho en todo tipo de navegadores.