Requirejs domReady plugin vs Jquery $ (document) .ready ()?

100

Używam RequireJS i muszę zainicjować coś na DOM gotowy. Teraz RequireJS dostarcza domReadywtyczkę , ale mamy już jQuery $(document).ready(), które jest dla mnie dostępne, ponieważ potrzebowałem jQuery.

Mam więc dwie możliwości:

  1. Użyj domReadywtyczki:

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

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

Którą wybrać i dlaczego?

Wydaje się, że obie opcje działają zgodnie z oczekiwaniami. Nie mam pewności co do jQuery, ponieważ RequireJS robi swoje; to znaczy, ponieważ RequireJS dynamicznie doda skrypty, obawiam się, że DOM gotowy może wystąpić przed załadowaniem wszystkich dynamicznie żądanych skryptów. Natomiast RequireJS spowoduje obciążenie dodatkowego JS tylko domReadywtedy, gdy mam już wymagane jQuery.

pytania

  • Dlaczego RequireJS zapewnia domReadywtyczkę, skoro możemy mieć jQuery $(document).ready();? Nie widzę żadnej korzyści z włączenia innej zależności.
  • Jeśli jest to tylko zaspokojenie potrzeb, dlaczego nie zapewnić takiego rozwiązania dla AJAX w różnych przeglądarkach?

O ile wiem, moduł, który wymaga domReady, nie zostanie pobrany ani wykonany po przygotowaniu dokumentu, a Ty możesz zrobić to samo wymagając jQuery:

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

Aby wyjaśnić moje pytanie: jaka jest różnica między wymaganiem domReadya jQuery?

Yugal Jindle
źródło
4
I am not confident in jquery's dom readychcę oznaczyć to jako obraźliwe:p
Dakait
3
Dom ready jQuery jest całkowicie niezawodny, nawet na IE. Miliony ludzi używają go codziennie, nie wiedząc ;-)
John Dvorak
1
Czy masz kontrolę nad tym, gdzie scripttrafiają Twoje tagi, czy piszesz bibliotekę / wtyczkę, której będą używać inne osoby (a więc to oni kontrolują lokalizację scripttagów w znacznikach)?
TJ Crowder
3
O Boże ... przeczytaj to z pełnym kontekstem. I am not confident in jquery's dom ready because requirejs is doing its magic.Ponieważ, require to hermetyzacja jquery w ograniczonym zakresie lokalnym. Nie o to chodzi. (jeśli chodzi o pytanie).
Yugal Jindle
1
Dzięki @TJCrowder za zmianę.
Yugal Jindle

Odpowiedzi:

91

Wygląda na to, że wszystkie kluczowe punkty zostały już trafione, ale kilka szczegółów wypadło przez pęknięcia. Głównie:

domReady

Jest to zarówno wtyczka, jak i moduł. Jeśli umieścisz go w tablicy wymagań z końcem, !twój moduł nie będzie wykonywany, dopóki nie będzie „bezpieczna” interakcji z DOM:

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

Zauważ, że ładowanie i wykonywanie są różne; chcesz, aby wszystkie pliki ładowały się tak szybko, jak to możliwe, to wykonanie zawartości jest wrażliwe na czas.

Jeśli pominiesz !, to zwykły moduł jest funkcją, która może przyjąć wywołanie zwrotne, które nie zostanie wykonane, zanim DOM będzie bezpieczny w interakcji:

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');        
});

Zalety korzystania z domReady jako wtyczki

Kod zależny od modułu, od którego z kolei zależy, domReady!ma bardzo istotną zaletę: nie trzeba czekać, aż DOM będzie gotowy!

Powiedzmy, że mamy blok kodu A, który zależy od modułu B, od którego zależy domReady!. Moduł B nie zakończy ładowania, zanim DOM będzie gotowy. Z kolei A nie będzie działać przed załadowaniem B.

Jeśli miałbyś używać domReadyjako zwykłego modułu w B, konieczne byłoby również, aby A zależał od domReady, a także zawinął swój kod wewnątrz domReady()wywołania funkcji.

Ponadto oznacza to, że domReady!cieszy się taką samą przewagą $(document).ready().

Odnośnie różnic między domReady i $ (document) .ready ()

Obydwaj węszą, czy / kiedy DOM jest gotowy w zasadniczo ten sam sposób.

Ponownie strach przed odpaleniem jQuery w niewłaściwym momencie

jQuery uruchomi wszystkie gotowe wywołania zwrotne, nawet jeśli DOM załaduje się przed jQuery (Twój kod nie powinien przejmować się tym, co nastąpi wcześniej).

fncomp
źródło
1
Pięknie, właśnie tego szukałem. Rozsądny, dobrze obsługiwany.
Yugal Jindle
Cieszę się, że mogłem pomóc :-)
fncomp
@YugalJindle Czy czegoś brakuje do nagrody? :)
fncomp
Właśnie testowałem to, co napisałeś - gotowe!
Yugal Jindle
Patrząc na kod wtyczki domReady ( github.com/requirejs/domReady/blob/master/domReady.js ) nie widzę powodu, dla którego miałbyś ładować go jako „domReady!” zamiast „domReady” - czy możesz wskazać mi fragment kodu, który powoduje tę zmianę w zachowaniu?
Jez
20

Próba odpowiedzi na twoje główne pytanie:

Dlaczego requirejsdostarcza domReadywtyczki, skoro możemy mieć jquery $(document).ready();?

Tak naprawdę robią dwie różne rzeczy. Zależność RequireJS domReadyoznacza, że ​​moduł ten wymaga pełnego załadowania modelu DOM, zanim będzie można go uruchomić (i dlatego można go znaleźć w dowolnej liczbie modułów w aplikacji, jeśli sobie tego życzysz), podczas gdy $(document).ready()zamiast tego uruchamia funkcje wywołania zwrotnego, gdy DOM jest ładowanie ukończone.

Różnica może wydawać się subtelna, ale pomyśl o tym: mam moduł, który musi być w jakiś sposób połączony z DOM, więc mogę polegać na nim domReadyi łączyć go w czasie definiowania modułu, lub umieścić $(document).ready()na końcu z wywołaniem zwrotnym do funkcji inicjującej moduł. Pierwsze podejście nazwałbym czystszym.

W międzyczasie, jeśli mam zdarzenie, które musi się wydarzyć zaraz po tym, jak DOM jest gotowy, $(document).ready()zdarzenie będzie celem, ponieważ nie zależy to w szczególności od ładowania modułów przez RequireJS, pod warunkiem, że zależą od kodu, do którego nazywając go z, są spełnione.

Warto również wziąć pod uwagę, że niekoniecznie używasz RequireJS z jQuery. Każdy moduł biblioteki, który potrzebuje dostępu do DOM (ale nie polega na jQuery), nadal byłby przydatny przy użyciu domReady.

Gert Sønderby
źródło
domReadynie jest zależnością dla requirejs. Byłaby to zależność dla kodu, jeśli używasz domReadyzdarzenia DocumentReady. Poza tym wydajesz się być zagubiony.
Yugal Jindle,
1
Świetna odpowiedź i ważna wskazówka dotycząca subtelności, z których wielu programistów często nie zdaje sobie sprawy (w tym ja ;-)).
Golo Roden
1
Yugal, mówiłem domReadyo zależności, ponieważ tak jest używana. Nie jako zależność od RequireJS, ale od modułu, w którym jest używana. Może powinienem to wyjaśnić w moim tekście, czy masz sugestie, jak to zrobić?
Gert Sønderby
Zobacz Update2 na pytanie. Może nie jesteśmy na tej samej stronie.
Yugal Jindle,
Yugal, co jeśli używasz MooTools? Qooxdoo? Coś nie jest jQuery? RequireJS nie jest żonaty z jQuery, chociaż wprawdzie bardzo dobrze ze sobą współpracują.
Gert Sønderby,
6

Odpowiadanie na pociski w kolejności ich pojawiania się:

  • Obaj osiągają to samo
  • Jeśli z jakiegokolwiek powodu masz zastrzeżenia do jquery, użyj domReady
  • Dobrze, więc po prostu użyj jQuery
  • Ponieważ nie wszyscy używają jQuery
  • Zgadzam się, po prostu użyj jQuery
  • Wtyczki z definicji „zaspokajają potrzebę”.
  • Ajax Cross Browser nie jest rzeczą. Między domenami? Prawdopodobnie jest, a jeśli nie, to nie ma potrzeby karmienia.
  • , -, -, - Dobrze

Kiedy do tego dojdzie, za bardzo się nad tym zastanawiasz. Jest to mechanizm wykonywania javascript w domReady. Gdybyś nie miał jQuery, byłbym zwolennikiem wtyczki domReady. Ponieważ masz jQuery, nie ładuj więcej skryptów, aby zrobić coś, co jest już dostępne.

Aktualizacja przejrzystości

Wtyczka domReady zbiera funkcje do wywołania, gdy dokument jest „gotowy”. Jeśli jest już załadowany, uruchamiają się natychmiast.

JQuery zbiera funkcje i wiąże odroczony obiekt z „gotowym” domem. Gdy dom jest gotowy, odroczony obiekt zostanie rozwiązany i funkcje zostaną uruchomione. Jeśli dom jest już `` gotowy '', to odroczony zostanie już rozwiązany, więc funkcja zostanie wykonana natychmiast.

Oznacza to, że skutecznie robią dokładnie to samo.

awbergs
źródło
0

Po kilku eksperymentach z requirejs z wieloma modułami sugeruję użycie domReady .

Zauważyłem, że funkcja skojarzona z $ (document) .ready (...) nie jest wywoływana, gdy requirejs ładuje wiele modułów. Podejrzewam, że dom przygotowuje się, zanim cały kod requirejs zostanie wykonany, a moduł obsługi wywołań zwrotnych jquery gotowy jest wywoływany, zanim zostanie powiązany z funkcją zdefiniowaną przez użytkownika, tj. W kodzie modułu głównego.

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.');
    });
});
Marcin Nowakowski
źródło
1
Wątpię, że jeśli masz wszystkie moduły na liście zależności, wszystkie zostaną pobrane i trafią do pamięci. post, że jquery zbiera wystąpienia dom.ready przed wykonaniem.
Yugal Jindle,
Jeśli DOM jest już gotowy, wywołanie zwrotne dla $(document).readyzostanie uruchomione natychmiast.
Danyal Aytekin,
-1

Zauważyłem, że robię to jako część głównego wpisu, dzięki czemu cały mój javascript ma gwarancję, że DOM jest gotowy, a jquery jest załadowany. Nie jestem pewien, jak wspaniale jest to mile widziane wszelkie opinie, ale oto mój 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');
        });
    });
});
Bil Simser
źródło