← Назад к вопросам

Как узнать что iframe загрузился?

2.3 Middle🔥 121 комментариев
#JavaScript Core

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Полные методы отслеживания загрузки iframe в браузере

Для определения момента загрузки iframe существует несколько подходов, различающихся по надежности и поддерживаемым сценариям.

Основные подходы

1. Событие load на самом iframe

Наиболее распространенный и простой способ — использование стандартного события load:

const iframe = document.createElement('iframe');
iframe.src = 'https://example.com';
document.body.appendChild(iframe);

iframe.addEventListener('load', function() {
    console.log('Iframe полностью загружен, включая все ресурсы');
    // Теперь можно безопасно взаимодействовать с содержимым
});

Важные нюансы:

  • Событие срабатывает после полной загрузки iframe со всем содержимым
  • Может возникнуть проблема Same-Origin Policy при попытке доступа к iframe.contentWindow
  • Для кросс-доменных iframe доступ к содержимому будет ограничен

2. Событие DOMContentLoaded

Если нужно отследить только готовность DOM (без изображений и стилей):

iframe.addEventListener('DOMContentLoaded', function() {
    console.log('DOM iframe готов, но ресурсы могут еще загружаться');
});

Работа с кросс-доменными iframe

PostMessage API

Для кросс-доменного взаимодействия используйте механизм сообщений:

В родительском окне:

const iframe = document.getElementById('external-frame');

window.addEventListener('message', function(event) {
    // Всегда проверяйте origin для безопасности!
    if (event.origin !== 'https://trusted-domain.com') return;
    
    if (event.data.type === 'LOAD_COMPLETE') {
        console.log('Iframe сообщил о завершении загрузки');
    }
});

iframe.src = 'https://trusted-domain.com/page';

В iframe (код на удаленном домене):

window.addEventListener('load', function() {
    window.parent.postMessage(
        { type: 'LOAD_COMPLETE', timestamp: Date.now() },
        'https://parent-domain.com'
    );
});

Продвинутые техники

MutationObserver для отслеживания изменений

Полезно, когда iframe динамически меняет свое содержимое:

const observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        if (mutation.type === 'childList') {
            console.log('Содержимое iframe изменилось');
        }
    });
});

const iframe = document.getElementById('dynamic-frame');
observer.observe(iframe.contentDocument.body, {
    childList: true,
    subtree: true
});

Интервальная проверка readyState

Для старых браузеров или особых случаев:

function waitForIframeLoad(iframe, callback) {
    const checkInterval = setInterval(function() {
        try {
            if (iframe.contentDocument.readyState === 'complete') {
                clearInterval(checkInterval);
                callback();
            }
        } catch (e) {
            // Ошибка возникает при кросс-доменном доступе
            // Нужно использовать другие методы
        }
    }, 100);
}

Особые случаи и обработка ошибок

Отслеживание ошибок загрузки

iframe.addEventListener('error', function(event) {
    console.error('Ошибка загрузки iframe:', event);
    // Можно показать fallback-контент
    iframe.style.display = 'none';
    document.getElementById('fallback').style.display = 'block';
});

Асинхронная загрузка с таймаутом

function loadIframeWithTimeout(url, timeout = 10000) {
    return new Promise((resolve, reject) => {
        const iframe = document.createElement('iframe');
        iframe.style.display = 'none';
        iframe.src = url;
        
        const timeoutId = setTimeout(() => {
            document.body.removeChild(iframe);
            reject(new Error('Таймаут загрузки iframe'));
        }, timeout);
        
        iframe.addEventListener('load', () => {
            clearTimeout(timeoutId);
            resolve(iframe);
        });
        
        iframe.addEventListener('error', () => {
            clearTimeout(timeoutId);
            reject(new Error('Ошибка загрузки iframe'));
        });
        
        document.body.appendChild(iframe);
    });
}

// Использование
loadIframeWithTimeout('https://example.com')
    .then(iframe => console.log('Успешно загружен'))
    .catch(error => console.error('Ошибка:', error));

Практические рекомендации

  1. Безопасность прежде всего: Всегда проверяйте event.origin при использовании postMessage
  2. Отказоустойчивость: Добавляйте обработчики ошибок и таймауты
  3. Производительность: Не создавайте много наблюдателей MutationObserver для одного iframe
  4. Совместимость: Для поддержки старых браузеров используйте полифиллы для postMessage и MutationObserver
  5. Ленивая загрузка: Для iframe вне области видимости используйте IntersectionObserver:
const lazyIframes = document.querySelectorAll('iframe[data-src]');
const io = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            const iframe = entry.target;
            iframe.src = iframe.dataset.src;
            io.unobserve(iframe);
        }
    });
});

lazyIframes.forEach(iframe => io.observe(iframe));

Выбор конкретного метода зависит от требований к безопасности, доменной политики и нужного уровня контроля над процессом загрузки. Для большинства случаев достаточно стандартного события load с обработкой ошибок.