web-dev-qa-db-fra.com

L'événement "load" ne se déclenche pas lorsque l'iframe est chargé dans Chrome

J'essaie d'afficher un "masque" sur mon client lorsqu'un fichier est généré dynamiquement côté serveur. Il semble que le travail recommandé pour contourner ce problème (car ce n’est pas ajax) consiste à utiliser un iframe et à écouter à partir de l’événement onload ou done pour déterminer à quel moment le fichier a effectivement été livré au client par le serveur.

voici mon code angulaire:

    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);

Cela fonctionne très bien dans Firefox mais pas de chance dans Chrome. J'ai aussi essayé d'utiliser la fonction onload:

e.onload = function()  { //unmask here }

Mais je n’ai pas eu de chance là non plus.

Des idées?

27
lostintranslation

Malheureusement, il n'est pas possible d'utiliser l'événement onload d'un iframe dans Chrome si le contenu est une pièce jointe. Cette réponse peut vous donner une idée de la façon dont vous pouvez la contourner.

19
rtcherry

Je déteste ça, mais je ne pouvais pas trouver un autre moyen que de vérifier s'il est toujours en cours de chargement, sauf en vérifiant à intervalles.

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);
10
Negarrak

Vous pouvez le faire d'une autre manière:

Dans le document 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);

Dans le document iframe (c'est le html de la page référencée par url)

    window.onload = function() {
        parent.iframeLoaded();
    }

Cela fonctionnera si la page principale et la page à l'intérieur de l'iframe sont dans le même domaine.

En fait, vous pouvez accéder au parent via:

window.parent
parent
//and, if the parent is the top-level document, and not inside another frame
top          
window.top

Il est plus sûr d'utiliser window.parent car les variables parent et top pourraient être écrasées (généralement sans intention). 

4
Carlos Robles

vous devez considérer 2 points:

1- Tout d'abord, si votre URL a un nom de domaine différent, il est impossible de le faire, sauf si vous avez accès à l'autre domaine pour ajouter l'en-tête Access-Control-Allow-Origin: *. Pour résoudre ce problème, accédez à ce lien .

2- mais s'il a le même domaine ou si vous avez ajouté Access-Control-Allow-Origin: * aux en-têtes de votre domaine, vous pouvez faire ce que vous voulez comme ceci:

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
    });
};

Je l'ai fait dans toutes sortes de navigateurs.

0
Mehran Hatami

Je viens de remarquer que Chrome ne déclenche pas toujours l'événement load pour la page principale, ce qui pourrait également avoir un effet sur les iframes, car ils sont fondamentalement traités de la même manière.

Utilisez Outils de développement ou l’API Performance pour vérifier si l’événement de chargement est déclenché.

Je viens de vérifier http://ee.co.uk/ et si vous ouvrez la console et entrez window.performance.timing, vous trouverez les entrées pour domComplete, loadEventStart et loadEventEnd valant 0 - au moins à ce jour temps:)

On dirait qu'il y a un problème avec Chrome ici - je l'ai vérifié sur 2 ordinateurs utilisant la dernière version 31.0.1650.63.

Mise à jour: vérifiez à nouveau ee et l'événement de chargement est déclenché, mais pas lors des rechargements ultérieurs; il s'agit donc d'un problème intermittent qui peut éventuellement être lié à des erreurs de chargement sur leur site. Mais l'événement de charge devrait déclencher n'importe quoi.

Ce problème s’est produit pour moi sur 5 ou 6 sites au cours de la dernière journée car j’ai remarqué que la surveillance de mon propre site échouait parfois. Seulement juste identifié la cause à cela. J'ai besoin d'un peu de sommeil de beauté, alors j'explorerai plus quand je serai plus éveillé.

0
Geezer68