Плагин Requirejs domReady против JQuery $ (document) .ready ()?

100

Я использую RequireJS, и мне нужно что-то инициализировать в DOM. Теперь RequireJS предоставляет domReadyплагин , но у нас уже есть jQuery $(document).ready(), который мне доступен, поскольку мне нужен jQuery.

Итак, у меня есть два варианта:

  1. Используйте domReadyплагин:

    require(['domReady'], function (domReady) {
        domReady(function () {
            // Do my stuff here...
        });
    });
    
  2. Использование $(document).ready():

    $(document).ready(function() {
        // Do my stuff here...
    });
    

Какой выбрать и почему?

Оба варианта работают, как ожидалось. Я не уверен в jQuery, потому что RequireJS творит чудеса; то есть, поскольку RequireJS будет динамически добавлять сценарии, меня беспокоит, что готовность DOM может произойти до того, как будут загружены все динамически запрашиваемые сценарии. Принимая во внимание, что RequireJS добавит нагрузку на дополнительный JS только domReadyтогда, когда мне уже требуется jQuery.

Вопросы

  • Почему RequireJS предоставляет domReadyплагин, если у нас может быть jQuery $(document).ready();? Я не вижу никаких преимуществ в включении другой зависимости.
  • Если это просто для удовлетворения потребности, то почему бы не предоставить его для кросс-браузерного AJAX?

Насколько я знаю, требующийся модуль domReadyне будет извлечен или выполнен после того, как документ будет готов, и вы можете сделать то же самое, требуя jQuery:

require(['jQuery'], function ($) {
    $(document).ready(function () {
        // Do my stuff here...
    });
});

Чтобы быть более ясным по моему вопросу: в чем разница между требованием domReadyили jQuery?

Югал Джиндл
источник
4
I am not confident in jquery's dom readyЯ хочу отметить это как оскорбление:p
Дакайт
3
jQuery dom ready совершенно надежен даже в IE. Миллионы людей используют его каждый день, не зная ;-)
Джон Дворжак
1
Вы контролируете, куда scriptидут ваши теги, или вы пишете библиотеку / плагин, которые будут использовать другие люди (и поэтому они контролируют расположение scriptтегов в разметке)?
TJ Crowder
3
О боже ... прочтите это с полным контекстом. I am not confident in jquery's dom ready because requirejs is doing its magic.Поскольку require инкапсулирует jquery в ограниченной локальной области. Дело не в этом. (что касается вопроса).
Югал Джиндл
1
Спасибо, @TJCrowder за редактирование.
Югал Джиндл,

Ответы:

91

Вроде бы все ключевые моменты уже были достигнуты, но некоторые детали провалились. В основном:

domReady

Это и плагин, и модуль. Если вы включите его в массив требований, !ваш модуль не будет выполняться до тех пор, пока не станет «безопасным» взаимодействовать с DOM:

define(['domReady!'], function () {
    console.info('The DOM is ready before I happen');
});

Обратите внимание, что загрузка и выполнение отличаются; вы хотите, чтобы все ваши файлы загружались как можно скорее, так как выполнение содержимого зависит от времени.

Если вы опустите !, то это просто обычный модуль, который оказывается функцией, которая может принимать обратный вызов, который не будет выполняться до того, как DOM станет безопасным для взаимодействия с:

define(['domReady'], function (domReady) {
    domReady(function () {
        console.info('The DOM is ready before I happen');
    });
    console.info('The DOM might not be ready before I happen');        
});

Преимущество использования domReady в качестве плагина

Код, который зависит от модуля, который, в свою очередь, зависит от модуля, domReady!имеет очень важное преимущество: ему не нужно ждать, пока DOM будет готов!

Скажем, у нас есть блок кода A, который зависит от модуля B, который зависит от domReady!. Модуль B не завершит загрузку, пока DOM не будет готов. В свою очередь, A не запустится, пока не загрузится B.

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

Кроме того, это означает, что domReady!пользуется тем же преимуществом $(document).ready().

Повторите различия между domReady и $ (document) .ready ()

Оба определяют, готова ли модель DOM и когда это происходит, по существу одинаково.

Опасайтесь того, что jQuery запустится не в то время

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

fncomp
источник
1
Красиво, это то, что я искал. Разумно, хорошо поддерживается.
Yugal Jindle
Рад, что смог помочь :-)
fncomp
@YugalJindle Что-то не хватает для награды? :)
fncomp
Я просто проверял то, что вы написали - держите!
Yugal Jindle
Глядя на код плагина domReady ( github.com/requirejs/domReady/blob/master/domReady.js ), я не вижу причин, по которым вам нужно загружать его как domReady! вместо domReady - не могли бы вы указать мне на фрагмент кода, который вызывает это изменение в поведении?
Jez
20

Попытка ответить на ваш главный вопрос:

Зачем requirejsнужен domReadyплагин, если у нас может быть jquery $(document).ready();?

На самом деле они делают две разные вещи. Зависимость RequireJS domReadyозначает, что этот модуль требует, чтобы DOM была полностью загружена, прежде чем его можно будет запустить (и поэтому его можно найти в любом количестве модулей в вашем приложении, если вы того пожелаете), в то время как $(document).ready()вместо этого запускает свои функции обратного вызова, когда DOM загрузка завершена.

Разница может показаться незначительной, но подумайте вот о чем: у меня есть модуль, который нужно каким-то образом связать с DOM, поэтому я могу либо зависеть от него domReadyи связать его во время определения модуля, либо поставить $(document).ready()в конце с обратным вызовом функции инициализации для модуля. Я бы назвал первый подход уборщиком.

Между тем, если у меня есть событие, которое должно произойти сразу после того, как DOM будет готов, это $(document).ready()событие будет подходящим , поскольку это, в частности, не зависит от того, как RequireJS выполняет загрузку модулей, при условии зависимостей кода, который вы звонящий из встречаются.

Также стоит учесть, что не обязательно использовать RequireJS с jQuery. Любой библиотечный модуль, которому требуется доступ к DOM (но не полагающийся на jQuery), будет по-прежнему полезен при использовании domReady.

Герт Сондерби
источник
domReadyне является зависимостью от requirejs. Это будет зависимость для кода, если вы используете domReadyсобытие DocumentReady. К тому же ты, кажется, сбиваешь с толку.
Yugal Jindle
1
Отличный ответ и важный намек на тонкости, которые многие разработчики часто не осознают (включая меня ;-)).
Golo Roden
1
Югал, я имел в виду domReadyзависимость, потому что это то, как она используется. Не как зависимость от RequireJS, а от модуля, в котором он используется. Может быть, мне стоит сделать это более ясным в моем тексте, у вас есть предложения, как?
Gert Sønderby
Пожалуйста, смотрите Update2 по этому вопросу. Может быть, мы не на одной странице.
Yugal Jindle
Югал, а если использовать MooTools? Qooxdoo? Что-нибудь не jQuery? RequireJS не связан с jQuery, хотя, по общему признанию, они действительно хорошо работают вместе.
Gert Sønderby
6

Отвечаем на пули в порядке появления:

  • Они оба делают одно и то же
  • Если у вас есть сомнения по поводу jquery по какой-либо причине, используйте domReady
  • Правильно, просто используйте jQuery
  • Потому что не все используют jQuery
  • Я согласен, просто используйте jQuery
  • Плагины по определению «кормят потребность».
  • Кроссбраузерный ajax - это не вещь. Перекрестный домен? Наверное, есть, а если нет, то и кормить нечего.
  • , -, -, - Хорошо

Когда дело доходит до этого, вы слишком много думаете об этом. Это механизм для выполнения javascript на domReady. Если бы у вас не было jQuery, я бы поддержал плагин domReady. Поскольку у вас есть jQuery, не загружайте больше скриптов для выполнения того, что уже доступно.

Обновление ясности

Плагин domReady собирает функции для вызова, когда документ «готов». Если он уже загружен, они выполняются немедленно.

JQuery собирает функции и связывает отложенный объект с «готовым» домом. Когда dom будет готов, отложенный объект будет разрешен, и функции будут запущены. Если dom уже «готов», то отложенный вызов уже будет разрешен, поэтому функция будет выполнена немедленно.

Это означает, что они фактически делают то же самое.

авберги
источник
0

После некоторых экспериментов с requirejs с несколькими модулями я предлагаю использовать domReady .

Я заметил, что функция, связанная с $ (document) .ready (...) , не вызывается, когда несколько модулей загружаются с помощью requirejs. Я подозреваю, что dom готовится до того, как будет выполнен весь код requirejs, и вызывается обработчик обратного вызова jquery ready до того, как он будет привязан к пользовательской функции, то есть в коде основного модуля.

require(['jquery',
    'underscore',
    'text!some_template.html',
    './my_module_1',
    './my_module_2',
    'domReady',
    'other_dependency_1',
    'other_dependency_2'
    ], function($, _, someTemplate, myModule1, myModule2, domReady) {

    $(document).ready(function() {
        console.info('This might never be executed.'); 
        console.info('Dom might get ready before requirejs would load modules.');
    });

    domReady(function () {
        console.info('This runs when the dom gets ready and modules are loaded.');
    });
});
Марцин Новаковски
источник
1
Я сомневаюсь, что если у вас есть все модули в вашем списке зависимостей, тогда все будут извлечены и попадут в память. сообщают, что jquery собирает экземпляры dom.ready перед выполнением.
Yugal Jindle
Если DOM уже готов, обратный вызов для $(document).readyбудет запущен немедленно.
Даньял Айтекин
-1

Я обнаружил, что делаю это как часть основной записи, чтобы для всего моего javascript было гарантировано, что DOM готов и jquery загружен. Не уверен, насколько это здорово, поэтому приветствую любые отзывы, но вот мой main.js:

require(['domReady!'], function(domReady){
    console.log('dom is ready');
    require(['jquery', 'bootstrap'], function(){
        console.log('jquery loaded');
        require(['app'], function(app){
            console.log('app loaded');
        });
    });
});
Бил Симсер
источник