Обратный вызов Javascript при завершении загрузки IFRAME?

Мне нужно выполнить обратный вызов, когда IFRAME закончил загрузку. Я не контролирую содержимое в IFRAME, поэтому я не могу запустить обратный вызов.

Этот IFRAME программно создан, и мне нужно передать его данные как переменную в обратном вызове, а также уничтожить iframe.

Любые идеи?

EDIT:

Вот что у меня есть сейчас:

function xssRequest(url, callback)
{
    var iFrameObj = document.createElement('IFRAME');
    iFrameObj.src = url;            
    document.body.appendChild(iFrameObj);   

    $(iFrameObj).load(function() 
    {
        document.body.removeChild(iFrameObj);
        callback(iFrameObj.innerHTML);
    });
}

Этот обратный вызов перед загрузкой iFrame, поэтому обратный вызов не возвращает данных.

Ответ 1

Сначала, перейдя по имени функции xssRequest, похоже, что вы пытаетесь выполнить запрос на кросс-сайт, который, если это так, вы не сможете прочитать содержимое iframe.

С другой стороны, если URL-адрес iframe находится в вашем домене, вы можете получить доступ к телу, но я обнаружил, что если я использую таймаут для удаления iframe, обратный вызов работает нормально:

// possibly excessive use of jQuery - but I've got a live working example in production
$('#myUniqueID').load(function () {
  if (typeof callback == 'function') {
    callback($('body', this.contentWindow.document).html());
  }
  setTimeout(function () {$('#frameId').remove();}, 50);
});

Ответ 2

Я использую jQuery, и на удивление это кажется загруженным, поскольку я только что протестировал и загрузил тяжелую страницу, и я не получил предупреждение в течение нескольких секунд, пока не увидел загрузку iframe:

$('#the_iframe').load(function(){
    alert('loaded!');
});

Итак, если вы не хотите использовать jQuery, посмотрите на их исходный код и посмотрите, будет ли эта функция работать по-разному с элементами iframe DOM, я буду смотреть на нее сам позже, когда мне интересно и опубликую здесь. Также я тестировал только последний хром.

Ответ 3

innerHTML вашего iframe пуст, потому что ваш тег iframe не окружает какой-либо контент в родительском документе. Чтобы получить контент со страницы, на которую ссылается атрибут iframe src, вам необходимо получить доступ к свойству iframe contentDocument. Исключение будет выбрано, если src из другого домена. Это функция безопасности, которая препятствует выполнению произвольного JavaScript на чужой странице, что создаст уязвимость межсайтового скриптинга. Вот пример кода, иллюстрирующий то, о чем я говорю:

<script src="http://prototypejs.org/assets/2009/8/31/prototype.js" type="text/javascript"></script>

<h1>Parent</h1>

<script type="text/javascript">
function on_load(iframe) {
  try {
    // Displays the first 50 chars in the innerHTML of the
    // body of the page that the iframe is showing.
    // EDIT 2012-04-17: for wider support, fallback to contentWindow.document
    var doc = iframe.contentDocument || iframe.contentWindow.document;
    alert(doc.body.innerHTML.substring(0, 50));
  } catch (e) {
    // This can happen if the src of the iframe is
    // on another domain
    alert('exception: ' + e);
  }
}
</script>
<iframe id="child" src="iframe_content.html" onload="on_load(this)"></iframe>

Для дальнейшего примера попробуйте использовать это как содержимое iframe:

<h1>Child</h1>

<a href="http://www.google.com/">Google</a>

<p>Use the preceeding link to change the src of the iframe
to see what happens when the src domain is different from
that of the parent page</p>

Ответ 4

Мне приходилось делать это в тех случаях, когда документы, такие как word docs и pdfs, передавались в iframe и находили решение, которое работает очень хорошо. Ключ обрабатывает событие onreadystatechanged в iframe.

Допустим, что имя вашего фрейма - "myIframe". Сначала где-то в вашем запуске кода (я делаю это inline, где после iframe) добавьте что-то вроде этого, чтобы зарегистрировать обработчик событий:

document.getElementById('myIframe').onreadystatechange = MyIframeReadyStateChanged;

Мне не удалось использовать атрибут onreadystatechage в iframe, я не могу вспомнить, почему, но приложение должно было работать в IE 7 и Safari 3, так что это может быть фактором.

Вот пример того, как получить полное состояние:

function MyIframeReadyStateChanged()
{
    if(document.getElementById('myIframe').readyState == 'complete')
    {
        // Do your complete stuff here.
    }
}

Ответ 5

Я хотел скрыть ожидающий spinner div, когда содержимое i-фрейма полностью загружено в IE, я буквально пробовал каждое решение, упомянутое в Stackoverflow.Com, но ничего не работал, как мне хотелось.

Тогда у меня появилась идея, что, когда содержимое i-кадра полностью загружено, может быть запущено событие загрузки $(Window). И это именно то, что произошло. Итак, я написал этот маленький script и работал как magic:

     $(window).load(function () {
     //alert("Done window ready ");
     var lblWait = document.getElementById("lblWait");
     if (lblWait != null ) {
         lblWait.style.visibility = "false";
         document.getElementById("divWait").style.display = "none";
     }
 });

Надеюсь, что это поможет.

Ответ 6

У меня есть аналогичный код в моих проектах, который отлично работает. Адаптация моего кода к вашей функции, решение может быть следующим:

function xssRequest(url, callback)
{
    var iFrameObj = document.createElement('IFRAME');
    iFrameObj.id = 'myUniqueID';
    document.body.appendChild(iFrameObj);       
    iFrameObj.src = url;                        

    $(iFrameObj).load(function() 
    {
        callback(window['myUniqueID'].document.body.innerHTML);
        document.body.removeChild(iFrameObj);
    });
}

Возможно, у вас есть пустой innerHTML, потому что (одна или обе причины): 1. вы должны использовать его против элемента тела 2. Вы удалили iframe со своей страницы DOM

Ответ 7

Я думаю, что событие загрузки правильное. Что не так, так это то, как вы используете для возврата содержимого из содержимого iframe dom.

Что вам нужно, это html страницы, загруженной в iframe, а не html объекта iframe.

Что вам нужно сделать, так это получить доступ к документу контента с помощью iFrameObj.contentDocument. Это возвращает dom страницы, загруженной внутри iframe, если она находится в том же домене текущей страницы.

Я хотел бы получить содержимое перед удалением iframe.

Я тестировал в firefox и opera.

Затем я думаю, что вы можете восстановить свои данные с помощью $(childDom).html() или $(childDom).find('some selector') ...

Ответ 8

У меня была аналогичная проблема, как и вы. Я сделал то, что я использую что-то, называемое jQuery. Что вы тогда делаете в коде javascript, это:

$(function(){ //this is regular jQuery code. It waits for the dom to load fully the first time you open the page.

    $("#myIframeId").load(function(){
       callback($("#myIframeId").html());
       $("#myIframeId").remove();

    });

});

Кажется, вы удаляете iFrame, прежде чем вы извлечете из него html. Теперь я вижу проблему с этим: p

Надеюсь, это поможет:).

Ответ 9

У меня была точно такая же проблема в прошлом, и единственный способ, которым я нашел исправление, - добавить обратный вызов на страницу iframe. Конечно, это работает только тогда, когда вы контролируете содержимое iframe.