Membutuhkan plugin js domReady vs Jquery $ (document) .ready ()?

100

Saya menggunakan RequireJS dan perlu menginisialisasi sesuatu di DOM siap. Sekarang, RequireJS menyediakan domReadyplugin , tetapi kami sudah memiliki jQuery $(document).ready(), yang tersedia untuk saya karena saya memerlukan jQuery.

Jadi saya punya dua pilihan:

  1. Gunakan domReadyplugin:

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

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

Mana yang harus saya pilih, dan mengapa?

Kedua opsi tersebut tampaknya berfungsi seperti yang diharapkan. Saya tidak yakin dengan jQuery karena RequireJS melakukan keajaibannya; yaitu, karena RequireJS akan menambahkan skrip secara dinamis, saya khawatir bahwa siap DOM mungkin terjadi sebelum semua skrip yang diminta secara dinamis dimuat. Padahal, RequireJS akan menambah beban pada JS tambahan hanya domReadyketika saya sudah memiliki jQuery yang dibutuhkan.

Pertanyaan

  • Mengapa RequireJS menyediakan domReadyplugin ketika kita bisa memiliki jQuery $(document).ready();? Saya tidak melihat keuntungan apa pun dari menyertakan ketergantungan lain.
  • Jika ini hanya untuk memenuhi kebutuhan, lalu mengapa tidak menyediakannya untuk AJAX lintas browser?

Sejauh yang saya tahu, modul yang membutuhkan domReadytidak akan diambil atau dieksekusi setelah dokumen siap, dan Anda juga dapat melakukan hal yang sama yang membutuhkan jQuery:

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

Untuk lebih jelasnya pertanyaan saya: apa perbedaan antara Requirement domReadyatau jQuery?

Yugal Jindle
sumber
4
I am not confident in jquery's dom readysaya ingin menandainya sebagai ofensif:p
Dakait
3
Dom ready jQuery sangat andal, bahkan di IE. Jutaan orang menggunakannya setiap hari tanpa mengetahuinya ;-)
John Dvorak
1
Apakah Anda mengontrol ke mana scripttag Anda pergi, atau apakah Anda menulis perpustakaan / plug-in yang akan digunakan orang lain (sehingga mereka mengontrol lokasi scripttag di markup)?
TJ Crowder
3
Ya Tuhan .. bacalah dengan konteks lengkap. I am not confident in jquery's dom ready because requirejs is doing its magic.Karena, Require adalah merangkum jquery dalam lingkup lokal yang terbatas. Bukan itu intinya. (sejauh pertanyaannya).
Yugal Jindle
1
Terima kasih, @TJCrowder untuk pengeditannya.
Yugal Jindle

Jawaban:

91

Sepertinya semua poin penting sudah tercapai, tetapi beberapa detail jatuh melalui celah. Terutama:

domReady

Ini adalah plugin dan modul. Jika Anda memasukkannya ke dalam larik persyaratan tanpa tambahan, !modul Anda tidak akan dieksekusi sampai "aman" untuk berinteraksi dengan DOM:

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

Perhatikan bahwa memuat dan mengeksekusi berbeda; Anda ingin semua file Anda dimuat secepat mungkin, itu adalah eksekusi konten yang peka waktu.

Jika Anda menghilangkan !, maka itu hanya modul normal yang kebetulan menjadi sebuah fungsi, yang dapat menerima callback yang tidak akan dijalankan sebelum DOM aman untuk berinteraksi dengan:

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

Keuntungan saat menggunakan domReady sebagai plugin

Kode yang bergantung pada modul yang pada gilirannya bergantung domReady!memiliki keuntungan yang sangat signifikan: Tidak perlu menunggu DOM siap!

Katakanlah kita memiliki blok kode, A, yang bergantung pada modul, B, yang bergantung domReady!. Modul B tidak akan selesai memuat sebelum DOM siap. Pada gilirannya, A tidak akan berjalan sebelum B dimuat.

Jika Anda akan menggunakannya domReadysebagai modul biasa di B, A juga perlu bergantung domReady, serta menggabungkan kodenya di dalam domReady()pemanggilan fungsi.

Lebih jauh, ini berarti domReady!menikmati keunggulan yang sama $(document).ready().

Re perbedaan antara domReady dan $ (document) .ready ()

Keduanya mengendus apakah DOM siap pada dasarnya dengan cara yang sama.

Kembali takut jQuery menembak pada waktu yang salah

jQuery akan mengaktifkan callback siap apa pun bahkan jika DOM dimuat sebelum jQuery melakukannya (kode Anda seharusnya tidak peduli mana yang terjadi lebih dulu.).

fncomp
sumber
1
Cantik, inilah yang saya cari. Wajar, didukung dengan baik.
Yugal Jindle
Senang bisa membantu :-)
fncomp
@YugalJindle Apakah ada sesuatu yang hilang untuk bounty? :)
fncomp
Saya baru saja menguji apa yang Anda tulis - ini dia!
Yugal Jindle
Melihat kode plugin domReady ( github.com/requirejs/domReady/blob/master/domReady.js ) Saya tidak melihat alasan mengapa Anda perlu memuatnya sebagai 'domReady!' alih-alih 'domReady' - bisakah Anda menunjukkan sedikit kode yang menyebabkan perubahan perilaku itu?
Jez
20

Upaya menjawab pertanyaan utama Anda:

Mengapa requirejsmenyediakan domReadyplugin ketika kita bisa memiliki jquery $(document).ready();?

Mereka melakukan dua hal yang berbeda. Ketergantungan RequireJS domReadymenandakan bahwa modul ini membutuhkan DOM untuk dimuat sepenuhnya sebelum dapat dijalankan (dan oleh karena itu dapat ditemukan di sejumlah modul dalam aplikasi Anda jika Anda menginginkannya), sementara $(document).ready()sebagai gantinya mengaktifkan fungsi panggilan baliknya ketika DOM selesai memuat.

Perbedaannya mungkin tampak tidak kentara, tetapi pikirkan ini: Saya memiliki modul yang perlu digabungkan ke DOM dalam beberapa cara, jadi saya dapat bergantung domReadydan memasangkannya pada waktu definisi modul, atau meletakkannya $(document).ready()di akhir. dengan panggilan balik ke fungsi init untuk modul. Saya akan menyebut pendekatan pertama lebih bersih.

Sementara itu, jika saya memiliki acara yang perlu terjadi tepat saat DOM siap, $(document).ready()acara tersebut akan menjadi tujuan, karena itu tidak secara khusus bergantung pada RequireJS yang sedang dilakukan memuat modul, asalkan dependensi kode Anda memanggilnya dari terpenuhi.

Perlu juga dipertimbangkan bahwa Anda tidak perlu menggunakan RequireJS dengan jQuery. Modul perpustakaan apa pun yang membutuhkan akses DOM (tetapi tidak bergantung pada jQuery) akan tetap berguna dengan menggunakan domReady.

Gert Sønderby
sumber
domReadybukan ketergantungan untuk requirejs. Ini akan menjadi ketergantungan untuk kode jika Anda menggunakan domReadyuntuk acara DocumentReady. Plus, Anda tampaknya membingungkan.
Yugal Jindle
1
Jawaban bagus, dan petunjuk penting tentang seluk-beluk yang sering tidak disadari oleh banyak pengembang (termasuk saya ;-)).
Golo Roden
1
Yugal, saya sebut domReadysebagai ketergantungan, karena begitulah penggunaannya. Bukan sebagai dependensi RequireJS, tetapi sebagai modul tempatnya digunakan. Mungkin saya harus membuatnya lebih jelas dalam teks saya, apakah Anda punya saran bagaimana?
Gert Sønderby
Silakan lihat Update2 pada pertanyaan itu. Bisa jadi kita tidak berada di halaman yang sama.
Yugal Jindle
Yugal, bagaimana jika Anda menggunakan MooTools? Qooxdoo? Ada yang bukan jQuery? RequireJS belum menikah dengan jQuery, meskipun mereka memang bekerja sama dengan sangat baik.
Gert Sønderby
6

Menjawab peluru Anda dalam urutan tampilan:

  • Mereka berdua melakukan hal yang sama
  • Jika Anda memiliki keraguan tentang jquery karena alasan apa pun, gunakan domReady
  • Benar, jadi gunakan saja jQuery
  • Karena tidak semua orang menggunakan jQuery
  • Saya setuju, gunakan saja jQuery
  • Plugin menurut definisi 'memberi makan kebutuhan'.
  • Cross Browser ajax bukanlah apa-apa. Lintas domain? Mungkin ada, dan jika tidak ada maka tidak perlu memberi makan.
  • , -, -, - Baik

Ketika sampai pada itu, Anda terlalu memikirkannya. Ini adalah mekanisme untuk mengeksekusi javascript di domReady. Jika Anda tidak memiliki jQuery, saya akan menganjurkan plugin domReady. Karena Anda memiliki jQuery maka jangan memuat lebih banyak skrip untuk melakukan sesuatu yang sudah tersedia.

Pembaruan Kejelasan

Plugin domReady mengumpulkan fungsi yang akan dipanggil saat dokumen 'siap'. Jika sudah dimuat maka mereka segera dieksekusi.

JQuery mengumpulkan fungsi dan mengikat objek yang ditangguhkan ke dom yang 'siap'. Saat dom siap, objek yang ditangguhkan akan diselesaikan dan fungsinya akan diaktifkan. Jika dom sudah 'ready' maka deferred sudah terselesaikan sehingga fungsi akan langsung dijalankan.

Artinya, secara efektif mereka melakukan hal yang persis sama.

awbergs
sumber
0

Setelah beberapa percobaan dengan requirejs dengan beberapa modul saya sarankan menggunakan domReady .

Saya perhatikan bahwa fungsi yang terkait dengan $ (document) .ready (...) tidak dipanggil ketika beberapa modul dimuat oleh requirejs. Saya menduga dom sedang bersiap-siap sebelum semua kode require dijalankan dan jquery ready callback handler dipanggil sebelum ia terikat dengan fungsi yang ditentukan pengguna yaitu dalam kode modul utama.

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
sumber
1
Saya ragu bahwa, Jika Anda memiliki semua modul dalam daftar ketergantungan Anda, maka semua akan diambil dan masuk ke memori. posting bahwa jquery mengumpulkan contoh dom.ready sebelum eksekusi.
Yugal Jindle
Jika DOM sudah siap, callback untuk $(document).readyakan segera dijalankan.
Danyal Aytekin
-1

Saya menemukan saya melakukan ini sebagai bagian dari entri utama sehingga semua javascript saya dijamin bahwa DOM sudah siap dan jquery dimuat. Tidak yakin seberapa hebat ini, kami menyambut baik umpan balik tetapi inilah main.js saya:

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
sumber