web-dev-qa-db-fra.com

Détection du chargement du contenu Iframe (Cross browser)

J'essaie de détecter quand un iframe et son contenu ont été chargés, sans avoir beaucoup de chance. Mon application prend des entrées dans les champs de texte de la fenêtre parente et met à jour l'iframe pour fournir un "aperçu en direct".

J'ai commencé avec le code suivant (YUI) pour détecter le moment où l'événement de chargement d'iframe se produit.

$E.on('preview-pane', 'load', function(){
    previewBody = $('preview-pane').contentWindow.document.getElementsByTagName('body')[0];
}

'preview-pane' est l'ID de mon iframe et j'utilise YUI pour attacher le gestionnaire d'événements. Cependant, la tentative d'accès au corps dans mon rappel (lors du chargement de l'iframe) échoue, car l'iframe se charge avant que le gestionnaire d'événements ne soit prêt. Ce code fonctionne si je retarde le chargement de l'iframe en rendant le script php qui le génère en veille.

Fondamentalement, je demande quelle est la bonne approche à travers les navigateurs pour détecter le moment où l’iframe est chargé et son document prêt?

82
David Snabel-Caunt

détecter quand l'iframe est chargé et que son document est prêt?

C'est idéal si vous pouvez obtenir que l'iframe vous dise lui-même à partir d'un script à l'intérieur du cadre. Par exemple, il peut appeler directement une fonction parent pour lui indiquer qu'elle est prête. L'exécution de code inter-images nécessite toujours une attention particulière, car les choses peuvent se produire dans un ordre imprévu. Une autre solution consiste à définir "var isready = true;" dans sa propre portée et à faire en sorte que le script parent détecte "contentWindow.isready" (et ajoute le gestionnaire de chargement onload, dans le cas contraire).

Si, pour une raison quelconque, il n'est pas pratique de faire coopérer le document iframe, vous rencontrez le problème traditionnel de la course de charge, à savoir que même si les éléments sont côte à côte:

<img id="x" ... />
<script type="text/javascript">
    document.getElementById('x').onload= function() {
        ...
    };
</script>

rien ne garantit que l'élément n'aura pas déjà été chargé au moment de l'exécution du script.

Les moyens de sortir des courses à la charge sont:

  1. sous IE, vous pouvez utiliser la propriété ‘readyState’ pour voir si quelque chose est déjà chargé;

  2. si l’objet est disponible uniquement avec JavaScript activé est acceptable, vous pouvez le créer de manière dynamique, en définissant la fonction d’événement "onload" avant de définir la source et d’ajouter à la page. Dans ce cas, il ne peut pas être chargé avant que le rappel ne soit défini;

  3. la manière old school de l'inclure dans le balisage:

    <img onload="callback(this)" ... />

Les gestionnaires HTML "onsomething" en ligne sont presque toujours la mauvaise chose et doivent être évités, mais dans ce cas, c'est parfois la moins mauvaise option.

70
bobince

Voir this blog. Il utilise jQuery, mais il devrait vous aider même si vous ne l'utilisez pas.

Fondamentalement, vous ajoutez ceci à votre document.ready()

$('iframe').load(function() {
    RunAfterIFrameLoaded();
});
45
kgiannakakis

Pour ceux qui utilisent React, détecter un événement de chargement iframe de même origine est aussi simple que de définir l'écouteur d'événement onLoad sur un élément iframe.

<iframe src={'path-to-iframe-source'} onLoad={this.loadListener} frameBorder={0} />

9
Farzad YZ

Pour toute personne utilisant Ember, cela devrait fonctionner comme prévu:

<iframe onLoad={{action 'actionName'}}  frameborder='0' src={{iframeSrc}} />
1
Max Wallace