Как проверить, загружен ли iframe или имеет контент? - PullRequest
65 голосов
/ 12 февраля 2012

У меня есть iframe с id = "myIframe", и вот мой код для загрузки его содержимого:

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

Проблема в том, что иногда загрузка занимает слишком много времени, а иногда загружается очень быстро.Поэтому я должен использовать функцию "setTimeout":

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

Все, что я хочу знать, - это как узнать, загружен ли iFrame или имеет контент.Использование iframe.contents().find() не будет работать.Я не могу использовать iframe.load(function(){}).

Ответы [ 10 ]

69 голосов
/ 04 мая 2012

Попробуйте это.

<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();"> 
37 голосов
/ 26 июля 2013

любезно используйте:

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

Обновлен мой ответ по мере изменения стандартов.

14 голосов
/ 28 апреля 2014

Самый простой вариант:

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

<iframe onload="frameload()" src=...>
9 голосов
/ 08 июня 2016

У меня была такая же проблема и я добавил ее, мне нужно было проверить, загружен ли iframe независимо от междоменной политики.Я разрабатывал расширение Chrome, которое внедряет определенный сценарий в веб-страницу и отображает некоторый контент с родительской страницы в iframe.Я попробовал следующий подход, и это сработало идеально для меня.
PS: В моем случае у меня есть контроль над содержимым в iframe, но не на родительском сайте.(Iframe размещается на моем собственном сервере)

Первое:
Создайте iframe с атрибутом data- в нем (эта часть была в сценарии с внедрением в моем случае)
<iframe id="myiframe" src="http://anyurl.com" data-isloaded="0"></iframe>

Теперь в коде iframe используйте:

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



Теперь вернемся к внедренному сценарию в моем случае:

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


и,

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



Это может не совсем точно ответить на вопрос, но это действительно возможный случай этого вопросакоторый я решил этим методом.

6 голосов
/ 12 февраля 2012

Я не уверен, что вы можете определить, загружен он или нет, но вы можете запустить событие, как только загрузка будет завершена:

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

РЕДАКТИРОВАТЬ: Как указал Джесси Халлетт, он всегда срабатывает, когда iframe загружен, даже если он уже был загружен. По сути, если iframe уже загружен, обратный вызов будет выполнен немедленно.

5 голосов
/ 22 октября 2015

Вы можете использовать событие iframe load для ответа при загрузке iframe.

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

Это не скажет вам, загружен ли правильный контент: Чтобы проверить это, вы можете проверить contentDocument.

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

Проверка contentDocument не будет работать, если iframe src указывает на другой домен, из которого выполняется ваш код.

4 голосов
/ 01 сентября 2017

в моем случае это была рамка из разных источников и иногда не загружалась.Решение, которое сработало для меня: если он успешно загружен, то, если вы попробуете этот код:

var iframe = document.getElementsByTagName('iframe')[0];
console.log(iframe.contentDocument);

, он не позволит вам получить доступ к contentDocument и, тем не менее, выдает ошибку перекрестного источника, еслине загружен успешно, то contentDocument вернет #document объект

2 голосов
/ 06 декабря 2013

Когда загружается iFrame, он изначально содержит #document, поэтому лучше всего проверить состояние загрузки, проверив, что там сейчас ..

if ($('iframe').contents().find('body').children().length > 0) {
    // is loaded
} else {
    // is not loaded
}
1 голос
/ 28 января 2018

Действительно замечательный метод - использовать jQuery AJAX. Родительский фрейм будет выглядеть так:

<iframe src="iframe_load.php" style="width: 100%; height: 100%;"></iframe>

Файл iframe_load.php загружает библиотеку jQuery и JavaScript, который пытается загрузить целевой URL в 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' ) ;
            } });

ВАЖНО Адресат должен содержать заголовок «Access-Control-Allow-Origin». Пример в PHP:

HEADER( "Access-Control-Allow-Origin: *" ) ;
0 голосов
/ 11 апреля 2019

Если вам нужно знать, когда iframe готов манипулировать, используйте интервал.В этом случае я «пингую» контент каждые 250 мс, и если внутри целевого iframe есть любой контент, останавливаю «ping» и что-то делаю.

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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...