Ich habe einen Iframe mit id = "myIframe" und hier meinen Code zum Laden des Inhalts:
$('#myIframe').attr("src", "my_url");
Das Problem ist, dass das Laden manchmal zu lange dauert und manchmal sehr schnell. Also muss ich die Funktion "setTimeout" verwenden:
setTimeout(function(){
if (//something shows iframe is loaded or has content)
{
//my code
}
else
{
$('#myIframe').attr("src",""); //stop loading content
}
},5000);
Ich möchte nur wissen, wie ich herausfinden kann, ob ein iFrame geladen ist oder Inhalt enthält. Die Verwendung iframe.contents().find()
funktioniert nicht. Ich kann nicht verwenden iframe.load(function(){})
.
javascript
jquery
iframe
Neuling29
quelle
quelle
Antworten:
Versuche dies.
<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();">
quelle
setTimeout(checkIframeLoaded, 100);
readyState === "complete"
hat den Trick ausgeführt, da er sich erst ändert, wenn alles geladen ist.iframe.contentDocument.location.href
Darstellung , wieabout:blank
. Dies scheint auch dann der Fall zu sein, wenn dassrc
für dasiframe
direkt im HTML angegeben ist.VM29320:1 Uncaught DOMException: Blocked a frame with origin "http://localhost:9002" from accessing a cross-origin frame.
Bitte verwenden Sie:
$('#myIframe').on('load', function(){ //your code (will be called once iframe is done loading) });
Meine Antwort wurde aktualisiert, als sich die Standards änderten.
quelle
iframe
s im Allgemeinen mit beginntsrc="about:blank"
, selbst wenn dassrc
direkt im HTML-iframe
Code angegeben ist oder bevor ein Knoten zum DOM hinzugefügt wird. Ich habe dies getestet, indem ich in einer engen Schleife auf IE11, Chrome und Edge nach deniframe
'scontentDocument.location.href
abgefragt habe. Es funktioniert auch nicht, wenn der gerahmte Inhalt über Meta-Tags oder Javascript umgeleitet wird.Ich hatte das gleiche Problem und fügte hinzu, ich musste überprüfen, ob iframe geladen ist, unabhängig von der domänenübergreifenden Richtlinie. Ich habe eine Chrome-Erweiterung entwickelt, die ein bestimmtes Skript in eine Webseite einfügt und Inhalte von der übergeordneten Seite in einem Iframe anzeigt. Ich habe versucht, dem Ansatz zu folgen, und das hat perfekt für mich funktioniert.
PS: In meinem Fall habe ich die Kontrolle über den Inhalt im Iframe, aber nicht auf der übergeordneten Site. (Iframe wird auf meinem eigenen Server gehostet.)
Erstens:
Erstellen Sie einen
data-
Iframe mit einem Attribut wie (dieser Teil war in meinem Fall in einem injizierten Skript).<iframe id="myiframe" src="http://anyurl.com" data-isloaded="0"></iframe>
Verwenden Sie nun im Iframe-Code:
var sourceURL = document.referrer; window.parent.postMessage('1',sourceURL);
Nun zurück zum injizierten Skript gemäß meinem Fall:
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);
und,
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'); } } }
Es mag die Frage nicht genau beantworten, aber es ist tatsächlich ein möglicher Fall dieser Frage, den ich mit dieser Methode gelöst habe.
quelle
Einfachste Option:
<script type="text/javascript"> function frameload(){ alert("iframe loaded") } </script> <iframe onload="frameload()" src=...>
quelle
Sie können das
load
Ereignis des Iframes verwenden , um zu reagieren, wenn der Iframe geladen wird.document.querySelector('iframe').onload = function(){ console.log('iframe loaded'); };
Dies sagt Ihnen nicht, ob der richtige Inhalt geladen wurde: Um dies zu überprüfen, können Sie den überprüfen
contentDocument
.document.querySelector('iframe').onload = function(){ var iframeBody = this.contentDocument.body; console.log('iframe loaded, body is: ', body); };
quelle
Ich bin nicht sicher, ob Sie erkennen können, ob es geladen ist oder nicht, aber Sie können ein Ereignis auslösen, sobald es geladen ist:
$(function(){ $('#myIframe').ready(function(){ //your code (will be called once iframe is done loading) }); });
EDIT: Wie von Jesse Hallett hervorgehoben, wird dies immer ausgelöst, wenn das
iframe
geladen hat, auch wenn es bereits geladen hat. Wenn also deriframe
bereits geladen wurde, wird der Rückruf im Wesentlichen sofort ausgeführt.quelle
$('#myIframe').load(function(){ })
ready
einen Iframe verwendet , führt die Funktion immer sofort aus, da sie für andere Dokumente als den Frame, in dem jQuery ausgeführt wird, nicht unterstützt wird.In meinem Fall war es ein Cross-Origin-Frame und wurde manchmal nicht geladen. Die Lösung, die für mich funktioniert hat, lautet: Wenn es erfolgreich geladen wurde, versuchen Sie diesen Code:
var iframe = document.getElementsByTagName('iframe')[0]; console.log(iframe.contentDocument);
Sie können nicht auf
contentDocument
einen Cross-Origin-Fehler zugreifen und diesen auslösen. Wenn der Frame jedoch nicht erfolgreich geladen wurde,contentDocument
wird ein#document
Objekt zurückgegebenquelle
Wenn ein iFrame geladen wird, enthält er zunächst das #document. Wenn Sie also den Ladezustand überprüfen, können Sie am besten überprüfen, was jetzt vorhanden ist.
if ($('iframe').contents().find('body').children().length > 0) { // is loaded } else { // is not loaded }
quelle
Ich habe einen Trick, der wie folgt funktioniert: [Cross-Browser nicht getestet!]
Definieren Sie den Onload-Ereignishandler von iframe, definiert als
$('#myIframe').on('load', function() { setTimeout(function() { try { console.log($('#myIframe')[0].contentWindow.document); } catch (e) { console.log(e); if (e.message.indexOf('Blocked a frame with origin') > -1 || e.message.indexOf('from accessing a cross-origin frame.') > -1) { alert('Same origin Iframe error found!!!'); //Do fallback handling if you want here } } }, 1000); });
Haftungsausschluss: Dies funktioniert nur für Dokumente mit dem gleichen Ursprung wie IFRAME.
quelle
Eine wirklich gute Methode ist die Verwendung von jQuery AJAX. Der übergeordnete Frame würde folgendermaßen aussehen:
<iframe src="iframe_load.php" style="width: 100%; height: 100%;"></iframe>
Die Datei iframe_load.php lädt die jQuery-Bibliothek und ein JavaScript, das versucht, die Ziel-URL in ein AJAX GET zu laden:
var the_url_to_load = "http://www.your-website.com" ; $.ajax({ type: "GET", url: the_url_to_load, data: "", success: function(data){ // if can load inside iframe, load the URL location.href = the_url_to_load ; }, statusCode: { 500: function() { alert( 'site has errors' ) ; } }, error:function (xhr, ajaxOptions, thrownError){ // if x-frame-options, site is down or web server is down alert( 'URL did not load due to x-frame-options' ) ; } });
WICHTIG Das Ziel muss den Header "Access-Control-Allow-Origin" enthalten. Beispiel in PHP:
HEADER( "Access-Control-Allow-Origin: *" ) ;
quelle
Wenn Sie wissen müssen, wann der Iframe manipulationsbereit ist, verwenden Sie ein Intervall. In diesem Fall habe ich „ping“ der Inhalt alle 250 ms und wenn es irgendwelche Inhalte innerhalb Ziel iframe, die „ping“ stoppen und etwas tun.
var checkIframeLoadedInterval = setInterval( checkIframeLoaded, 250 ); function checkIframeLoaded() { var iframe_content = $('iframe').contents(); if (iframe_content.length > 0) { clearInterval(checkIframeLoadedInterval); //Apply styles to the button setTimeout(function () { //Do something inside the iframe iframe_content.find("body .whatever").css("background-color", "red"); }, 100); //100 ms of grace time } }
quelle
Wenn Sie die Seite und den Iframe in derselben Domain hosten , können Sie auf das
Window.DOMContentLoaded
Ereignis des Iframes warten . Sie müssen warten, bis die Originalseite ausgelöst wird,DOMContentLoaded
und dann einenDOMContentLoaded
Ereignis-Listener an den Iframe anhängenWindow
.Vorausgesetzt, Sie haben einen Iframe wie folgt:
<iframe id="iframe-id" name="iframe-name" src="..."></iframe>
Mit dem nächsten Snippet können Sie sich in das
DOMContentLoaded
Ereignis des Iframes einbinden :document.addEventListener('DOMContentLoaded', function () { var iframeWindow = frames['iframe-name']; // var iframeWindow = document.querySelector('#iframe-id').contentWindow // var iframeWindow = document.getElementById('iframe-id').contentWindow iframeWindow.addEventListener('DOMContentLoaded', function () { console.log('iframe DOM is loaded!'); }); });
quelle