Ожидание появления элемента в DOM JavaScript и jQuery
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Чтобы выполнить код после того, как DOM-элемент появится на странице, используйте API MutationObserver
. Этот метод не требует использования jQuery или установки таймеров и является достаточно эффективным. Вот короткий пример кода, который поможет вам решить эту задачу:
const waitForElement = (selector, callback) => {
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.matches && node.matches(selector)) {
callback(node);
observer.disconnect();
}
});
});
});
observer.observe(document.body, { childList: true, subtree: true });
};
// Пример использования
waitForElement('#myElement', element => {
// Код, выполняющийся после обнаружения элемента '#myElement' в DOM
console.log('Элемент найден:', element);
});
Для более подробных объяснений, описания альтернативных методов и запасных решений продолжайте чтение.
Использование последних методов
Async/Await и промисы
Перепишем код, представленный выше, с использованием промисов. Это позволит применять await
внутри асинхронной функции для упрощения работы.
const elementReady = selector => new Promise(resolve => {
const observer = new MutationObserver((mutations, obs) => {
if (document.querySelector(selector)) {
resolve(document.querySelector(selector)); // Промис выполнен, элемент найден
obs.disconnect();
}
});
observer.observe(document.body, { childList: true, subtree: true });
});
// Использование с async/await
(async () => {
const element = await elementReady('#myElement');
// Работа с обнаруженным элементом
console.log('Async/await: Элемент загружен:', element);
})();
Запасной вариант с DOMNodeInserted
Если API MutationObserver
не поддерживается в вашем окружении, можно использовать событие DOMNodeInserted
. Это хороший вариант за счет совместимости со старыми браузерами.
function backupOnElementReady(selector, callback) {
document.addEventListener('DOMNodeInserted', event => {
if (event.target.matches(selector)) {
callback(event.target); // Элемент, который мы искали
}
});
}
Учтите, что событие DOMNodeInserted
срабатывает довольно часто, поэтому оно может негативно повлиять на производительность. Используйте его с осторожностью.
Старые методы выполнения
Проверка наличия элемента посредством интервалов
Для тех, кто предпочитает использовать setInterval
вместо MutationObserver
, следующий код для проверки присутствия элемента:
const checkForElement = (selector, callback, interval = 100) => {
const intervalCheck = setInterval(() => {
const element = document.querySelector(selector);
if (element) {
callback(element);
clearInterval(intervalCheck);
}
}, interval);
};
Этот метод может снизить производительность, особенно при частых проверках или сложности структуры страницы.
Время ожидания для нетерпеливых
А если элемент так и не появляется, несмотря на ожидание? В этом случае можно установить таймаут:
const waitForElementWithTimeout = (selector, callback, timeout = 3000) => {
const startTime = Date.now();
const interval = setInterval(() => {
const element = document.querySelector(selector);
const timeElapsed = Date.now() – startTime;
if (element) {
callback(element);
clearInterval(interval);
} else if (timeElapsed > timeout) {
console.warn(`Время ожидания элемента ${selector} превышено: ${timeout} мс.`);
clearInterval(interval);
}
}, 100);
};
Добавление предупреждения о времени ожидания поможет сэкономить время.
Визуализация
Представьте, что вы ожидаете прилёт голубя (🐦 — DOM-элемент), который принесёт вам посылку на цифровой балкон (окно браузера).
function pigeonsParcelDelivery(selector) {
waitForElement(selector, pigeon => {
console.log('🐦 Голубь привёз посылку:', pigeon);
// Пора распаковывать отправление!
});
}
Процесс работы pigeonsParcelDelivery
выглядит так:
⌚ Ожидаем голубя 🐦...
⏳ Голубь ещё в пути...
🎁 Голубь прибыл с посылкой!
Завершение
Как только появляется необходимый элемент, вам, возможно, потребуется добавить дополнительную логику для его интеграции в приложение.
waitForElement('#myElement', element => {
processElement({
element, // Этот элемент теперь передается следующей функции
extraParam: 'value', // Можно добавить любые другие необходимые параметры
});
});
Таким образом, обнаружение элемента может стать триггером для запуска следующего этапа работы приложения.