НейроАгент

Полная альтернатива jQuery Ready

Замените document.ready() jQuery на нативные методы JavaScript. Изучите события DOMContentLoaded, проверки readyState и кросс-браузерные решения для современных и устаревших браузеров.

Вопрос

Эквивалент $.ready() в чистом JavaScript - как вызвать функцию, когда страница/DOM готова

В jQuery мы все знаем замечательную функцию .ready():

javascript
$('document').ready(function(){});

Однако, допустим, я хочу запустить функцию, написанную на стандартном JavaScript без использования библиотек, и запустить её как только страница будет готова её обработать. Какой правильный подход к этому?

Я знаю, что могу сделать:

javascript
window.onload="myFunction()";

Или я могу использовать тег body:

html
<body onload="myFunction()">

Или я даже могу попробовать в конце страницы после всего, перед закрывающими тегами body или html, например:

html
<script type="text/javascript">
    myFunction();
</script>

Какой кросс-браузерный (работающий как в старых, так и в новых браузерах) метод существует для вызова одной или нескольких функций, подобно jQuery’s $.ready()?

НейроАгент

Ванильный JavaScript эквивалент jQuery $.ready()

Основным ванильным JavaScript эквивалентом jQuery $.ready() является событие DOMContentLoaded, которое срабатывает, когда первоначальный HTML-документ полностью загружен и обработан, без ожидания загрузки таблиц стилей, изображений и фреймов. Для кроссбраузерной совместимости, включая старые версии Internet Explorer, потребуется более комплексное решение, которое проверяет состояние готовности документа и использует соответствующие обработчики событий для разных браузеров.

Содержание

Решение для современных браузеров

Наиболее прямой подход для современных браузеров — использование события DOMContentLoaded:

javascript
document.addEventListener("DOMContentLoaded", function() {
    // Ваш код здесь
    console.log("DOM готов!");
});

Это прямой эквивалент jQuery $(document).ready() и работает во всех современных браузерах, включая Chrome, Firefox, Safari и IE9+ [источник]. Событие срабатывает, когда DOM полностью загружен, но до завершения загрузки изображений и других внешних ресурсов, что делает его быстрее, чем window.onload.

Кроссбраузерная реализация

Для полной кроссбраузерной совместимости, включая старые версии Internet Explorer, требуется более надежное решение. Вот комплексная реализация, которая обрабатывает все браузеры от IE6 и выше:

javascript
function docReady(fn) {
    // Проверяем, доступен ли DOM уже
    if (document.readyState === "complete" || document.readyState === "interactive") {
        // Вызываем на следующем доступном тике
        setTimeout(fn, 1);
    } else {
        // Используем DOMContentLoaded для современных браузеров
        document.addEventListener("DOMContentLoaded", fn);
    }
}

// Использование
docReady(function() {
    // Ваш код здесь
    console.log("DOM готов!");
});

Для еще более широкой совместимости, включая IE8 и ниже, вот улучшенная версия:

javascript
function ready(fn) {
    // Проверяем, загружен ли DOM уже
    if (document.readyState !== 'loading') {
        fn();
    } else if (document.addEventListener) {
        // Для современных браузеров
        document.addEventListener('DOMContentLoaded', fn);
    } else {
        // Для IE8 и ниже
        document.attachEvent('onreadystatechange', function() {
            if (document.readyState === 'complete') {
                fn();
            }
        });
    }
}

// Использование
ready(function() {
    // Ваш код здесь
    console.log("DOM готов!");
});

Эта реализация обрабатывает различные способы, которыми браузеры сигнализируют о готовности DOM, работая во всех основных браузерах, включая IE6+ [источник]. Согласно решению для кроссбраузерности Рэймона Шоуэнаара, этот подход охватывает все версии браузеров.

Альтернативные подходы

Прямая проверка состояния документа

Можно проверить состояние готовности документа без использования событий:

javascript
function domReady(callback) {
    if (document.readyState === "interactive" || document.readyState === "complete") {
        callback();
    } else {
        document.addEventListener("DOMContentLoaded", callback);
    }
}

domReady(function() {
    // Ваш код здесь
});

Этот метод, как объясняется на Beeker.io, проверяет текущее состояние и либо выполняет немедленно, либо ожидает события.

Скрипт с атрибутом defer

Просто добавьте атрибут defer к тегу вашего скрипта:

html
<script src="your-script.js" defer></script>

Атрибут defer указывает браузеру загружать скрипт без блокировки разбора HTML и выполнять его после того, как документ будет обработан, но до DOMContentLoaded [источник]. Как упоминается в обсуждении на Reddit, это современная альтернатива функции ready jQuery.

Скрипт в конце body

Разместите тег вашего скрипта прямо перед закрывающим тегом </body>:

html
<!DOCTYPE html>
<html>
<head>
    <title>Название страницы</title>
</head>
<body>
    <!-- Ваш контент здесь -->
    
    <script>
        // Ваш код здесь
        console.log("DOM готов!");
    </script>
</body>
</html>

Это самый простой подход, который надежно работает во всех браузерах, хотя он не так гибок, как решения на основе событий [источник].

Совместимость с браузерами

Вот обзор совместимости для разных подходов:

Метод IE6-8 IE9+ Chrome Firefox Safari Opera
DOMContentLoaded
onreadystatechange
document.readyState
Размещение скрипта
Атрибут defer

Событие DOMContentLoaded поддерживается более чем 98% браузеров, но не IE8 и ниже [источник]. Для полной совместимости необходимо комбинировать несколько подходов, как показано в кроссбраузерной реализации.

Рекомендуемое решение

Для большинства современных проектов я рекомендую эту кроссбраузерную функцию ready:

javascript
function domReady(callback) {
    // Если DOM уже загружен, выполнить callback
    if (document.readyState === 'interactive' || document.readyState === 'complete') {
        callback();
    } else {
        // Для современных браузеров
        document.addEventListener('DOMContentLoaded', callback);
        
        // Для IE8 и ниже
        if (document.attachEvent) {
            document.attachEvent('onreadystatechange', function() {
                if (document.readyState === 'complete') {
                    callback();
                }
            });
        }
    }
}

// Использование
domReady(function() {
    // Можно добавить несколько функций
    initializeComponents();
    setupEventListeners();
    loadDynamicContent();
});

// Или создать пространство имен для нескольких функций
var DOMReady = {
    callbacks: [],
    
    add: function(callback) {
        if (document.readyState === 'interactive' || document.readyState === 'complete') {
            callback();
        } else {
            this.callbacks.push(callback);
        }
    },
    
    ready: function() {
        var callbacks = this.callbacks;
        for (var i = 0; i < callbacks.length; i++) {
            callbacks[i]();
        }
    }
};

// Добавьте ваши функции
DOMReady.add(function() {
    console.log("Первая функция готова");
});

DOMReady.add(function() {
    console.log("Вторая функция готова");
});

// Инициализировать при готовности DOM
domReady(DOMReady.ready);

Это решение обеспечивает:

  • Полную кроссбраузерную совместимость (IE6+)
  • Поддержку нескольких callback-функций
  • Немедленное выполнение, если DOM уже готов
  • Чистую, переиспользуемую структуру кода

Согласно статье на CSS-Tricks, этот подход эффективно работает во всех браузерах, сохраняя чистый, независимый от зависимостей код.


Источники

  1. Stack Overflow - Ванильный JavaScript эквивалент jQuery $.ready()
  2. GitHub - vanilla-ready
  3. Reddit - Что использовать вместо jQuery $(document).ready()?
  4. Stack Overflow - Какой не-jQuery эквивалент ‘$(document).ready()’?
  5. Raymon Schouwenaar - Кроссбраузерный Document Ready с ванильным JavaScript
  6. Beeker.io - jQuery $(document).ready() эквивалент в ванильном JavaScript
  7. CSS-Tricks - Кроссбраузерный независимый от зависимостей DOM Ready
  8. Wikitechy - $(document).ready эквивалент без jQuery
  9. WPShout - jQuery document.ready в ванильном JavaScript
  10. SitePoint - Замена функции jQuery Document Ready на JavaScript

Заключение

Ванильный JavaScript эквивалент jQuery $.ready() можно реализовать несколькими способами в зависимости от требований к совместимости с браузерами:

  1. Для современных браузеров: Используйте document.addEventListener("DOMContentLoaded", callback) — это самый чистый и прямой подход
  2. Для полной кроссбраузерной совместимости: Реализуйте функцию, которая проверяет document.readyState и использует как addEventListener, так и attachEvent для старых версий IE
  3. Для простоты: Размещайте скрипты в конце body или используйте атрибут defer
  4. Для нескольких функций: Создайте функцию ready, которая поддерживает массив callback-функций

Рекомендуемый подход сочетает современную обработку событий с поддержкой наследия, обеспечивая работу вашего кода во всех браузерах от IE6 до последних версий. Это решение сохраняет такое же поведение, как функция ready jQuery, при этом будучи легковесным и независимым от зависимостей.

Помните, что хотя window.onload работает, он ожидает загрузки всех ресурсов (изображений, таблиц стилей и т.д.), в то время как DOM-ready срабатывает, как только HTML-структура становится доступной, что делает его быстрее и более похожим на поведение jQuery.