Mam iframe z id = "myIframe" i tutaj mój kod do załadowania jego zawartości:
$('#myIframe').attr("src", "my_url");
Problem polega na tym, że czasami ładowanie trwa zbyt długo, a czasami ładuje się bardzo szybko. Muszę więc użyć funkcji „setTimeout”:
setTimeout(function(){
if (//something shows iframe is loaded or has content)
{
//my code
}
else
{
$('#myIframe').attr("src",""); //stop loading content
}
},5000);
Chcę tylko wiedzieć, jak sprawdzić, czy element iFrame jest załadowany lub zawiera zawartość. Używanie iframe.contents().find()
nie zadziała. Nie mogę użyć iframe.load(function(){})
.
javascript
jquery
iframe
nowicjusz29
źródło
źródło
Odpowiedzi:
Spróbuj tego.
<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();">
źródło
setTimeout(checkIframeLoaded, 100);
readyState === "complete"
zadziałało, ponieważ nie zmienia się, dopóki wszystko nie zostanie załadowane.iframe.contentDocument.location.href
wyświetlaniem jakoabout:blank
. Wydaje się, że jest to prawdą, nawet jeślisrc
for theiframe
jest określone bezpośrednio w kodzie HTML.VM29320:1 Uncaught DOMException: Blocked a frame with origin "http://localhost:9002" from accessing a cross-origin frame.
uprzejmie użyj:
$('#myIframe').on('load', function(){ //your code (will be called once iframe is done loading) });
Zaktualizowałem moją odpowiedź, gdy zmieniły się standardy.
źródło
iframe
zazwyczaj zaczyna się odsrc="about:blank"
, nawet jeślisrc
jest on określony bezpośrednio w kodzie HTML lub przed dodaniemiframe
węzła do DOM. Przetestowałem to, sprawdzając, czyiframe
sącontentDocument.location.href
w ciasnej pętli w IE11, Chrome i Edge. Nie działa również, jeśli zawartość w ramce przekierowuje za pomocą metatagów lub kodu JavaScript.Miałem ten sam problem i dodałem do tego, musiałem sprawdzić, czy ramka iframe jest ładowana niezależnie od zasad międzydomenowych. Pracowałem nad rozszerzeniem do Chrome, które wstawia pewien skrypt na stronę internetową i wyświetla część treści ze strony nadrzędnej w ramce iframe. Próbowałem zastosować podejście i to zadziałało idealnie dla mnie.
PS: W moim przypadku mam kontrolę nad zawartością elementu iframe, ale nie w witrynie nadrzędnej. (Element iframe jest hostowany na moim własnym serwerze)
Po pierwsze:
Utwórz element iframe z
data-
atrybutem w nim takim jak (ta część była w skrypcie wstrzykniętym w moim przypadku)<iframe id="myiframe" src="http://anyurl.com" data-isloaded="0"></iframe>
Teraz w kodzie iframe użyj:
var sourceURL = document.referrer; window.parent.postMessage('1',sourceURL);
Wróćmy teraz do wstrzykniętego skryptu, jak w moim przypadku:
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);
i,
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'); } } }
Może nie do końca odpowiada na to pytanie, ale rzeczywiście jest to możliwy przypadek tego pytania, które rozwiązałem tą metodą.
źródło
Najłatwiejsza opcja:
<script type="text/javascript"> function frameload(){ alert("iframe loaded") } </script> <iframe onload="frameload()" src=...>
źródło
Możesz użyć
load
zdarzenia iframe, aby odpowiedzieć na załadowanie elementu iframe.document.querySelector('iframe').onload = function(){ console.log('iframe loaded'); };
Nie powie Ci, czy załadowano poprawną zawartość: Aby to sprawdzić, możesz sprawdzić plik
contentDocument
.document.querySelector('iframe').onload = function(){ var iframeBody = this.contentDocument.body; console.log('iframe loaded, body is: ', body); };
źródło
Nie jestem pewien, czy możesz wykryć, czy jest załadowany, czy nie, ale możesz uruchomić zdarzenie po zakończeniu ładowania:
$(function(){ $('#myIframe').ready(function(){ //your code (will be called once iframe is done loading) }); });
EDYCJA: Jak zauważył Jesse Hallett, będzie to zawsze uruchamiane po
iframe
załadowaniu, nawet jeśli już zostało. Zasadniczo więc, jeśli plikiframe
został już załadowany, wywołanie zwrotne zostanie wykonane natychmiast.źródło
$('#myIframe').load(function(){ })
ready
iframe zawsze spowoduje natychmiastowe wykonanie funkcji, ponieważ nie jest ona obsługiwana w innych dokumentach niż ramka, w której działa jQuery.w moim przypadku była to ramka cross-origin i czasami się nie ładowała. rozwiązanie, które zadziałało dla mnie, to: jeśli zostało pomyślnie załadowane, jeśli spróbujesz tego kodu:
var iframe = document.getElementsByTagName('iframe')[0]; console.log(iframe.contentDocument);
nie pozwoli ci uzyskać dostępu
contentDocument
i zgłosić błędu z różnych źródeł, jednak jeśli ramka nie zostanie załadowana pomyślniecontentDocument
, zwróci#document
obiektźródło
Kiedy element iFrame jest ładowany, początkowo zawiera #document, więc sprawdzenie stanu obciążenia może działać najlepiej, sprawdzając, co jest teraz.
if ($('iframe').contents().find('body').children().length > 0) { // is loaded } else { // is not loaded }
źródło
Oto sztuczka działająca w następujący sposób: [nie testowałem różnych przeglądarek!]
Zdefiniuj procedurę obsługi zdarzeń onload elementu iframe zdefiniowaną jako
$('#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); });
Zastrzeżenie: działa tylko w przypadku dokumentów IFRAME SAMEGO POCHODZENIA.
źródło
Naprawdę świetną metodą jest użycie jQuery AJAX. Ramka nadrzędna wyglądałaby następująco:
<iframe src="iframe_load.php" style="width: 100%; height: 100%;"></iframe>
Plik iframe_load.php załadowałby bibliotekę jQuery i JavaScript, który próbuje załadować docelowy adres URL w AJAX GET:
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' ) ; } });
WAŻNE Miejsce docelowe musi zawierać nagłówek „Access-Control-Allow-Origin”. Przykład w PHP:
HEADER( "Access-Control-Allow-Origin: *" ) ;
źródło
Jeśli chcesz wiedzieć, kiedy element iframe jest gotowy do manipulacji, użyj interwału. W tym przypadku „pinguję” zawartość co 250 ms i jeśli w docelowym elemencie iframe jest jakaś zawartość, zatrzymuję „ping” i coś zrób.
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 } }
źródło
Jeśli hostujesz stronę i element iframe w tej samej domenie , możesz nasłuchiwać
Window.DOMContentLoaded
zdarzenia elementu iframe . MusiszDOMContentLoaded
najpierw poczekać na uruchomienie oryginalnej strony , a następnie dołączyćDOMContentLoaded
detektor zdarzeń do elementu iframeWindow
.Biorąc pod uwagę, że masz następujący element iframe,
<iframe id="iframe-id" name="iframe-name" src="..."></iframe>
następny fragment pozwoli Ci podłączyć się do
DOMContentLoaded
zdarzenia elementu iframe :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!'); }); });
źródło