Визначення завантаження вмісту Iframe (перехресний браузер)


90

Я намагаюся виявити, коли iframe та його вміст завантажуються, але не надто щастить. Моя програма робить певний ввід у текстових полях у батьківському вікні та оновлює iframe, надаючи "попередній перегляд"

Я розпочав з наступного коду (YUI), щоб виявити, коли відбувається подія завантаження iframe.

$E.on('preview-pane', 'load', function(){
    previewBody = $('preview-pane').contentWindow.document.getElementsByTagName('body')[0];
}

'preview-pane' - це ідентифікатор мого iframe, і я використовую YUI для приєднання обробника події. Однак спроба отримати доступ до тіла мого зворотного виклику (при завантаженні iframe) не вдається, я думаю, тому що iframe завантажується до того, як обробник події готовий. Цей код працює, якщо я затримую завантаження iframe, роблячи скрипт php, який генерує його, сплячим.

В основному, я запитую, який правильний підхід у браузерах визначати, коли iframe завантажується і його документ готовий?


1
Починати з YUI - погана ідея (як і будь-яка інша бібліотека JS). Чому? Тому що ви просто не можете знати, яку магію робить ця бібліотека. Якщо вони не можуть повністю підтримувати "завантаження", то краще зробіть це самостійно у зрозумілому та читабельному javascript.
Крістіан

2
Ви часто можете прочитати вихідний код бібліотеки @Christian. Я вважаю, що це зазвичай дає вам чудові поради щодо того, як зробити це самостійно, незалежно від того, використовуєте ви їх реалізацію чи ні.
AJP

@AJP Ви неправильно зрозуміли мою думку. Якщо ви робите щось, у чому не впевнені, краще мати менше коду, щоб було менше місця для помилок.
Крістіан

2
Залежить від того, як ви на це дивитесь. Тоді я знав, що обробка подій YUI працювала, тому мені не довелося турбуватися про цю частину коду. Я також знав, як написати власний обробник addEvent, не те що він працював краще, ніж YUI, щодо цієї проблеми.
Девід Снабель-Коунт

1
@Nico Питання стосується YUI, а $ - псевдонім обгортки Dom від YUI.
Девід Снабель-Коунт

Відповіді:


73

виявити, коли iframe завантажився і його документ готовий?

Ідеально, якщо ви зможете отримати iframe, щоб розповісти вам сам із сценарію всередині кадру. Наприклад, він може викликати батьківську функцію безпосередньо, щоб повідомити, що вона готова. Завжди потрібна обережність при виконанні крос-кадрового коду, оскільки речі можуть відбуватися в такому порядку, якого ви не очікуєте. Інша альтернатива - встановити 'var isready = true;' у власному обсязі, і мати батьківський скрипт sniff для 'contentWindow.isready' (і додайте обробник onload, якщо ні).

Якщо з якихось причин непрактично співпрацювати документ iframe, у вас є традиційна проблема швидкості навантаження, а саме така, що навіть якщо елементи знаходяться поруч один з одним:

<img id="x" ... />
<script type="text/javascript">
    document.getElementById('x').onload= function() {
        ...
    };
</script>

немає гарантії, що елемент не буде завантажений до моменту запуску сценарію.

Способи виходу з перегонів:

  1. в IE ви можете використовувати властивість 'readyState', щоб побачити, чи щось вже завантажено;

  2. якщо допустимо мати елемент, доступний лише з увімкненим JavaScript, ви можете створити його динамічно, встановивши функцію події «завантаження» перед встановленням джерела та додаванням на сторінку. У цьому випадку його не можна завантажити до встановлення зворотного виклику;

  3. олдскульний спосіб включення його в розмітку:

    <img onload="callback(this)" ... />

Вбудовані обробники "onsomething" у HTML майже завжди є неправильною річчю, якої слід уникати, але в цьому випадку іноді це найменш поганий варіант.


Дякую. Моє рішення перевіряє ReadyState (якщо він існує), а потім елементи тіла внутрішньої довжини HTML, щоб перевірити, чи завантажився він. Якщо ні, приєднує обробник події завантаження. Здається, це працює нормально
Девід Снабель-Коунт

8
-1 - вбудовані події не є "поганими", це лише поточна мода. Насправді вбудовані події легше налагоджувати та розуміти, на відміну від їхніх магічних аналогів (які, з іншого боку, легше прикріплювати, складати та використовувати безперешкодно).
Крістіан

1
@Christian, вбудовані події також є найкращим варіантом, коли вам потрібно долучити подію до кожного елементу дуже довгого списку. Оскільки ви вже циклічно створюєте список на стороні сервера, набагато ефективніше також приєднати вбудовану подію.
haknick

16
@haknick Чи не хочете ви використовувати один прослуховувач подій у списку та використовувати делегат події? Це було б ефективніше.
Девід Снабель-Коунт,

4
Це не буде працювати, якщо iframe є міждоменним. Сценарій всередині iframe не може отримати доступ до батьківського вікна.
Sudheer Someshwara

48

Дивіться цю публікацію в блозі. Він використовує jQuery, але він повинен допомогти вам, навіть якщо ви не використовуєте його.

В основному ви додаєте це до свого document.ready()

$('iframe').load(function() {
    RunAfterIFrameLoaded();
});

Цікаво, але у мене проблема полягає у подіях завантаження та термінах. Я прислухаюсь до події навантаження, як зазначено в цій статті.
Девід Снабель-Коунт,

я спробував це за допомогою console.log. він реєструється після завантаження iframe.
shorif2000

12

Для тих, хто використовує React, виявити подію завантаження iframe того самого походження так само просто, як встановити onLoadпрослуховувач події для елемента iframe.

<iframe src={'path-to-iframe-source'} onLoad={this.loadListener} frameBorder={0} />


Чи може onLoadподія спрацьовувати лише для iframe того самого походження?
L_K

2

Для всіх, хто використовує Ember, це має працювати, як очікувалося:

<iframe onLoad={{action 'actionName'}}  frameborder='0' src={{iframeSrc}} />
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.