119 votes

Comment vérifier que l'iframe est chargée ou qu'elle a un contenu ?

J'ai une iframe avec id = "myIframe" et voici mon code pour charger son contenu :

$('#myIframe').attr("src", "my_url");

Le problème est que le chargement est parfois trop long et parfois très rapide. Je dois donc utiliser la fonction "setTimeout" :

setTimeout(function(){
   if (//something shows iframe is loaded or has content)
   {
       //my code
   }
   else
   {
       $('#myIframe').attr("src",""); //stop loading content
   }
},5000);

Tout ce que je veux savoir, c'est comment savoir si une iFrame est chargée ou si elle a un contenu. En utilisant iframe.contents().find() ne fonctionnera pas. Je ne peux pas utiliser iframe.load(function(){}) .

0 votes

Vous ne voulez donc pas que l'iframe charge quoi que ce soit s'il lui faut plus de 5 secondes pour le faire ?

0 votes

Merci pour votre aide :) . Oui, je ne veux pas que l'iframe charge quoi que ce soit si elle met plus de 5 secondes à se charger. L'utilisation de ".ready()" comme vous le montrez ci-dessous ne fonctionne pas.

0 votes

113voto

Biranchi Points 4417

Essayez ceci.

<script>
function checkIframeLoaded() {
    // Get a handle to the iframe element
    var iframe = document.getElementById('i_frame');
    var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;

    // Check if loading is complete
    if (  iframeDoc.readyState  == 'complete' ) {
        //iframe.contentWindow.alert("Hello");
        iframe.contentWindow.onload = function(){
            alert("I am loaded");
        };
        // The loading is complete, call the function we want executed once the iframe is loaded
        afterLoading();
        return;
    } 

    // If we are here, it is not loaded. Set things up so we check   the status again in 100 milliseconds
    window.setTimeout(checkIframeLoaded, 100);
}

function afterLoading(){
    alert("I am here");
}
</script>

<body onload="checkIframeLoaded();">

24 votes

Démérites pour avoir passé une chaîne de caractères à setTimeout(). Il est plus propre de passer une référence de fonction : setTimeout(checkIframeLoaded, 100);

4 votes

Celui-ci conduit à "Unsafe JavaScript attempt to access frame with URL url1 from frame with url2 Domains, protocols and ports must match." (Tentative JavaScript non sécurisée d'accès à un cadre avec URL url1 depuis un cadre avec url2).

0 votes

C'était la meilleure solution pour ce que j'essayais d'accomplir. J'utilise AngularJS à l'intérieur de l'iFrame, et j'utilise ng-include, qui retarde le chargement des fichiers inclus. J'essayais d'imprimer le contenu de l'Iframe lors de l'événement onload, mais il se déclenchait trop tôt. En vérifiant la présence de readyState === "complete" a fait l'affaire, puisqu'il ne change pas tant que tout n'est pas chargé.

51voto

pratikabu Points 846

À utiliser avec bienveillance :

$('#myIframe').on('load', function(){
    //your code (will be called once iframe is done loading)
});

J'ai mis à jour ma réponse car les normes ont changé.

14 votes

Cette approche ne fonctionne pas du tout car l'événement se déclenche immédiatement parce que iframe commencent généralement par src="about:blank" même si le src est spécifié directement dans le code HTML ou avant un iframe est ajouté au DOM. J'ai testé cela en interrogeant le nœud iframe 's contentDocument.location.href dans une boucle serrée sur IE11, Chrome et Edge. Cela ne fonctionne pas non plus si le contenu encadré effectue des redirections via des balises méta ou du javascript.

26voto

Tushar Shukla Points 1187

J'ai eu le même problème et en plus, j'ai eu besoin de vérifier si l'iframe est chargée indépendamment de la politique cross-domain. Je développais une extension chrome qui injecte certains script sur une page web et affiche du contenu de la page parent dans une iframe. J'ai essayé l'approche suivante et cela a parfaitement fonctionné pour moi.
P.S. : Dans mon cas, je peux contrôler le contenu de l'iframe mais pas celui du site parent. (L'iframe est hébergée sur mon propre serveur)

Premièrement :
Créer une iframe avec un data- comme suit (cette partie était dans le script injecté dans mon cas)
<iframe id="myiframe" src="http://anyurl.com" data-isloaded="0"></iframe>

Maintenant, dans le code de l'iframe, utilisez :

var sourceURL = document.referrer;
window.parent.postMessage('1',sourceURL);

Revenons maintenant au script injecté dans mon cas :

setTimeout(function(){
  var myIframe = document.getElementById('myiframe');
  var isLoaded = myIframe.prop('data-isloaded');
  if(isLoaded != '1')
  {
    console.log('iframe failed to load');
  } else {
    console.log('iframe loaded');
  }
},3000);

et,

window.addEventListener("message", receiveMessage, false);
function receiveMessage(event)
{
    if(event.origin !== 'https://someWebsite.com') //check origin of message for security reasons
    {
        console.log('URL issues');
        return;
    }
    else {
        var myMsg = event.data;
        if(myMsg == '1'){
            //8-12-18 changed from 'data-isload' to 'data-isloaded
            $("#myiframe").prop('data-isloaded', '1');
        }
    }           
}

Cela ne répond peut-être pas exactement à la question, mais c'est en effet un cas possible de cette question que j'ai résolu par cette méthode.

17voto

Orane Points 76

Option la plus simple :

<script type="text/javascript">
  function frameload(){
   alert("iframe loaded")
  }
</script>

<iframe onload="frameload()" src=...>

13 votes

N'est pas une solution solide car elle donne l'alerte même si l'url est cassée.

9voto

mheiber Points 290

Vous pouvez utiliser la fonction load pour réagir au chargement de l'iframe.

document.querySelector('iframe').onload = function(){
    console.log('iframe loaded');
};

Cela ne vous permettra pas de savoir si le contenu correct a été chargé : Pour le vérifier, vous pouvez inspecter l'élément contentDocument .

document.querySelector('iframe').onload = function(){
    var iframeBody = this.contentDocument.body;
    console.log('iframe loaded, body is: ', body);
};

Vérification de la contentDocument ne fonctionnera pas si l'iframe src pointe vers un domaine différent de celui où s'exécute votre code.

2 votes

Veuillez envisager d'éditer votre message pour ajouter plus d'explications sur ce que fait votre code et pourquoi il résoudra le problème. Une réponse qui ne contient que du code (même s'il fonctionne) n'aide généralement pas l'OP à comprendre son problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X