jQuery: обеспечить порядок выполнения вызовов document.ready()

Я работаю над кодовой базой с несколькими блоками кода, устанавливающими некоторое поведение в document.ready() (jQuery). Есть ли способ заставить один конкретный блок вызываться перед любым другим?

Предыстория: мне нужно обнаруживать ошибки JS в среде автоматизированного тестирования, поэтому мне нужен код, который начинает регистрировать ошибки JS для выполнения до выполнения любого другого кода JS.


person Ankit Soni    schedule 04.06.2012    source источник
comment
Действительно ли блок кода регистрации ошибок должен ждать готовности DOM?   -  person Kevin B    schedule 04.06.2012
comment
@KevinB Отличный момент! Может быть, даже стоит этого не ждать...   -  person msanford    schedule 04.06.2012
comment
@KevinB Я не очень хорошо знаком с JS. Если я поместил код вне любого блока, будет ли гарантировано, что он запустится до того, как будет выполнен любой другой код?   -  person Ankit Soni    schedule 04.06.2012
comment
Он работает именно там, где вы поместите его в свой DOM. Если это первый тег скрипта на вашей странице (скажем, в верхней части вашего HTML head), он будет запущен первым.   -  person Paul    schedule 04.06.2012
comment
@AnkitSoni при условии, что он помещен в теги html, а все остальные блоки кода зависят от DOMReady, он будет выполняться перед любым кодом в блоках DOMReady.   -  person Kevin B    schedule 04.06.2012
comment
@KevinB Хорошо, я только что проверил это, оказывается, мне нужно дождаться готовности DOM. В противном случае детали сообщения об ошибке (сообщение, URL-адрес, номер строки) не определены.   -  person Ankit Soni    schedule 04.06.2012


Ответы (5)


document.ready() обратные вызовы вызываются в том порядке, в котором они были зарегистрированы. Если вы сначала зарегистрируете свой тестовый обратный вызов, он будет вызван первым.

Кроме того, если вашему тестовому коду на самом деле не нужно манипулировать DOM, вы можете запустить его по мере анализа кода и не ждать, пока DOM будет готов, который будет запущен до того, как будут вызваны другие document.ready() обратные вызовы. Или, возможно, вы могли бы запустить часть своего тестового кода немедленно и отложить только ту часть, которая использует DOM, до document.ready().

Другая идея (только для целей тестирования) заключается в том, что вы можете работать со слегка измененной версией jQuery, которая добавляет флаг к document.ready(), который при передаче и установке в true указывает на вызов этой функции в первую очередь, или вы можете добавить новый метод document.readyFirst(), который будет вызывать ваш функция в первую очередь. Это потребует незначительных изменений в коде обработки document.ready() в jQuery.

person jfriend00    schedule 04.06.2012
comment
@AnkitSoni - Почему вы удалили тег лучшего ответа 8 месяцев спустя? Что изменилось? - person jfriend00; 17.02.2013
comment
Моя ошибка, добавил обратно. Напротив, я снова имел в виду это, поскольку это все еще полезно! - person Ankit Soni; 19.02.2013

Поскольку @jfriend00 упоминает, что ready callbacks are called in the order they were registered.

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

jQuery(document).ready(function(){
    jQuery(document).ready(function(){
        // This block will be executed after all ready calls.
    });
});
person ecabuk    schedule 29.02.2016
comment
Этот метод действительно работает, но я могу себе представить, что в некоторых случаях он дает довольно странные результаты. Кроме того, у него повсюду запах кода, и это довольно запутанно для будущих разработчиков, поддерживающих код. - person Edwin; 13.04.2016
comment
Могу подтвердить, что это работает, но это действительно странно. Может быть очень запутанным, если у вас есть несколько звонков, которые вы хотите заказать. - person Sebastien; 15.07.2020

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

person jncraton    schedule 04.06.2012

Я пытался сделать что-то подобное, я загружал кучу полифилов с функциями .ready(), но у меня также были свои собственные .ready() на странице, которые мне нужно было выполнить в первую очередь, хотя полифиллы были загружены в заголовок .

Я нашел хороший способ обойти это, имея .ready() очень рано (сразу после загрузки jQuery), который выполняет функции из массива. Поскольку это очень ранний исходный код, .ready() выполняется первым. Далее на странице я могу добавить функции в массив, и поэтому все они будут выполняться перед любыми другими .ready().

Я завернул его в функцию .beforeReady() и разместил на GitHub как jQuery-Before-Ready для всех, кому это интересно. https://github.com/aim12340/jQuery-Before-Ready

person EamonnM    schedule 18.04.2017

Вы можете выполнить код запуска ведения журнала в DOMReady и другую инициализацию в load. Или вы можете создать свой собственный менеджер инициализации, который сначала вызывает код запуска ведения журнала, а затем все остальные обратные вызовы инициализации (при условии, что они зарегистрированы в вашем менеджере, а не в jQuery, если только вы не хотите взломать jQuery и извлечь их оттуда, что я не делаю) т советую).

person Mr. TA    schedule 04.06.2012