Как заменить $(document).ready() на чистом JavaScript без jQuery?
Основной способ: событие DOMContentLoaded
Самый правильный и рекомендуемый аналог $(document).ready() в чистом JavaScript — это использование события DOMContentLoaded. Оно срабатывает сразу после того, как браузер полностью загрузил и распарсил HTML-документ, но до загрузки изображений, стилей и других внешних ресурсов.
Вот как это выглядит:
document.addEventListener('DOMContentLoaded', function() {
// Ваш код выполнится после полной загрузки DOM
console.log('DOM готов!');
document.querySelector('.my-class').textContent = 'Привет!';
});
Если вы используете стрелочную функцию (современный синтаксис):
document.addEventListener('DOMContentLoaded', () => {
// код
});
Второй способ: размещение скрипта перед закрывающим тегом </body>
Это самый простой и часто используемый метод. Если вы поместите тег <script> прямо перед </body>, то к моменту его выполнения весь DOM уже будет построен. Никаких дополнительных обработчиков не нужно:
<!DOCTYPE html>
<html>
<head>
<title>Моя страница</title>
</head>
<body>
<div class="my-class">Текст</div>
<!-- Скрипт в конце body -->
<script>
// DOM уже загружен, можно работать
document.querySelector('.my-class').textContent = 'Привет!';
</script>
</body>
</html>
Третий способ: атрибут defer в теге <script>
Современный и элегантный способ. Атрибут defer говорит браузеру: «Загружай скрипт параллельно с HTML, но выполни только после полного парсинга документа». Это работает даже если скрипт находится в <head>:
<!DOCTYPE html>
<html>
<head>
<title>Моя страница</title>
<script defer src="script.js"></script>
</head>
<body>
<div class="my-class">Текст</div>
</body>
</html>
В файле script.js вы можете писать код без обёрток:
// Этот код выполнится после загрузки DOM
document.querySelector('.my-class').textContent = 'Привет!';
Важные отличия от jQuery
- DOMContentLoaded vs load: Событие
load(window.onload) ждёт загрузки ВСЕХ ресурсов (картинки, iframe и т.д.) — это аналог$(window).on('load', fn), а неready(). - Несколько обработчиков: Вы можете добавить сколько угодно подписчиков на
DOMContentLoaded— они все выполнятся по очереди. - Проверка готовности: Если DOM уже загружен, а вы подписываетесь на событие, оно не сработает. Для защиты используйте проверку
document.readyState:
function onDOMReady(callback) {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback);
} else {
callback(); // DOM уже готов, вызываем сразу
}
}
// Использование:
onDOMReady(() => {
console.log('DOM готов!');
});
Итог: лучший способ в 2024 году — использовать defer для внешних скриптов или DOMContentLoaded для inline-скриптов. Это даёт ту же функциональность, что и jQuery, но без лишнего веса библиотеки.
Альтернатива: самодельная функция-замена ready()
Если вы хотите сохранить привычный синтаксис в стиле jQuery, можно написать свою маленькую функцию-обёртку:
function ready(fn) {
if (document.readyState !== 'loading') {
fn();
} else {
document.addEventListener('DOMContentLoaded', fn);
}
}
// Используем почти как в jQuery:
ready(function() {
console.log('DOM готов!');
document.querySelector('.my-class').textContent = 'Работает!';
});
Этот код проверяет, не загружен ли уже DOM. Если да — вызывает функцию сразу, если нет — подписывается на событие.
Для очень старых браузеров (IE8 и ниже)
Если вам нужно поддерживать совсем древние браузеры, можно использовать событие onreadystatechange:
document.onreadystatechange = function() {
if (document.readyState === 'interactive' || document.readyState === 'complete') {
// Ваш код
}
};
Но в современной разработке это не нужно — все актуальные браузеры поддерживают DOMContentLoaded и defer.
Совет: Начните с defer — это самый простой способ, который не требует написания лишнего кода и работает «из коробки».