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





асинхронный функцию (9)


Я должен был сделать это в тех случаях, когда документы, такие как текстовые документы и pdf-файлы, были переданы в 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.
    }
}

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

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

Есть идеи?

РЕДАКТИРОВАТЬ:

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

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, поэтому обратный вызов не возвращает данных.




ВнутреннийHTML вашего iframe пуст, потому что ваш тег iframe не окружает какой-либо контент в родительском документе. Чтобы получить контент со страницы, на которую ссылается атрибут src iframe, вам нужно получить доступ к свойству contentDocument iframe. Исключение будет выбрано, если 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>



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

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

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




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

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. вы должны использовать его против элемента body 2. вы удалили iframe с вашей страницы DOM




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




Использование onload attrbute решит вашу проблему.

Вот пример.

function a() {
alert("Your iframe has been loaded");
}
<iframe src="https://.com" onload="a()"></iframe>

Это то, что вы хотите?

Щелкните здесь для получения дополнительной информации.




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

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

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

Я бы отвлек содержимое до удаления iframe.

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

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




Прежде всего, перейдя по имени функции 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);
});



Если вы используете его, библиотека Underscore.js имеет метод clone .

var newObject = _.clone(oldObject);




javascript events dom iframe