Requirejs domReady plugin เทียบกับ 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 ready อาจเกิดขึ้นก่อนที่สคริปต์ที่ร้องขอแบบไดนามิกทั้งหมดจะโหลด ในขณะที่ 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
Dakait

3
Dom ของ jQuery นั้นเชื่อถือได้อย่างสมบูรณ์แบบแม้กระทั่งใน IE ผู้คนนับล้านใช้มันทุกวันโดยไม่รู้ตัว ;-)
John Dvorak

1
คุณเป็นผู้ควบคุมว่าscriptแท็กของคุณไปที่ใดหรือคุณกำลังเขียนไลบรารี / ปลั๊กอินที่คนอื่นจะใช้ (ดังนั้นพวกเขาจึงควบคุมตำแหน่งของscriptแท็กในมาร์กอัป) หรือไม่
TJ Crowder

3
โอ้พระเจ้า .. อ่านด้วยบริบทเต็ม ๆ I am not confident in jquery's dom ready because requirejs is doing its magic.เนื่องจากต้องมีการห่อหุ้ม jquery ในขอบเขตเฉพาะที่ จำกัด นั่นไม่ใช่ประเด็น (เท่าที่สงสัย).
ยูกัลจินเดิล

1
ขอบคุณ @TJCrowder สำหรับการแก้ไข
Yugal Jindle

คำตอบ:


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 ก็จำเป็นdomReadyเช่นกันที่A จะต้องขึ้นอยู่กับเช่นเดียวกับการตัดรหัสภายในการdomReady()เรียกใช้ฟังก์ชัน

นอกจากนี้หมายความdomReady!ว่ามีข้อได้เปรียบเหมือนกัน$(document).ready()มีความสุขที่ได้เปรียบเดียวกันซ้ำ

ความแตกต่างระหว่าง domReady และ $ (เอกสาร) พร้อม ()

ทั้งคู่ดูว่า DOM พร้อมในลักษณะเดียวกันหรือไม่

กลัว jQuery ยิงผิดเวลา

jQuery จะเริ่มการเรียกกลับที่พร้อมใช้งานแม้ว่า DOM จะโหลดก่อนที่ jQuery จะทำก็ตาม (โค้ดของคุณไม่ควรสนใจว่าจะเกิดขึ้นก่อน)


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();?

พวกเขาทำสองสิ่งที่แตกต่างกันจริงๆ การdomReadyพึ่งพาของ RequireJS แสดงว่าโมดูลนี้ต้องการให้ DOM โหลดอย่างสมบูรณ์ก่อนจึงจะสามารถรันได้ (ดังนั้นจึงสามารถพบได้ในโมดูลจำนวนเท่าใดก็ได้ในแอปพลิเคชันของคุณหากคุณต้องการ) ในขณะที่$(document).ready()จะเริ่มการทำงานของฟังก์ชันการเรียกกลับแทนเมื่อ DOM เป็น โหลดเสร็จแล้ว

ความแตกต่างอาจดูละเอียดอ่อน แต่ลองนึกถึงสิ่งนี้: ฉันมีโมดูลที่ต้องเชื่อมต่อกับ DOM ไม่ทางใดก็ทางหนึ่งดังนั้นฉันจึงสามารถพึ่งพาdomReadyและจับคู่ตามเวลาที่กำหนดโมดูลหรือวางไว้$(document).ready()ที่ส่วนท้ายของมัน ด้วยการเรียกกลับไปยังฟังก์ชัน init สำหรับโมดูล ฉันจะเรียกวิธีทำความสะอาดครั้งแรก

ในขณะเดียวกันถ้าฉันมีเหตุการณ์ที่จำเป็นต้องเกิดขึ้นเนื่องจาก DOM พร้อมแล้วไฟล์ $(document).ready()เหตุการณ์นั้นจะเป็นสิ่งที่ต้องทำเนื่องจากไม่ได้ขึ้นอยู่กับ RequireJS ที่กำลังโหลดโมดูลเสร็จสิ้นโดยมีการอ้างอิงของโค้ดที่คุณ เรียกจากพบ

นอกจากนี้ยังควรพิจารณาด้วยว่าคุณไม่จำเป็นต้องใช้ RequireJS กับ jQuery โมดูลไลบรารีใด ๆ ที่ต้องการการเข้าถึง DOM (แต่ไม่ต้องพึ่งพา jQuery) จะยังคงมีประโยชน์โดยใช้domReady.


domReadyไม่ใช่การพึ่งพาสำหรับความต้องการ js มันจะเป็นการอ้างอิงสำหรับรหัสถ้าคุณใช้domReadyสำหรับเหตุการณ์ DocumentReady นอกจากนี้คุณดูเหมือนจะสับสน
Yugal Jindle

1
คำตอบที่ยอดเยี่ยมและคำแนะนำที่สำคัญสำหรับรายละเอียดปลีกย่อยที่นักพัฒนาหลายคนมักไม่ตระหนัก (รวมถึงตัวฉันเองด้วย ;-))
Golo Roden

1
ยูกัลฉันหมายถึงdomReadyการพึ่งพาเพราะนั่นคือวิธีที่ใช้ ไม่ใช่การขึ้นต่อกันของ RequireJS แต่เป็นของโมดูลที่ใช้ บางทีฉันควรทำให้ชัดเจนขึ้นในข้อความของฉันคุณมีคำแนะนำสำหรับวิธีการอย่างไร
Gert Sønderby

โปรดดูUpdate2ในคำถาม อาจเป็นเราไม่ได้อยู่ในหน้าเดียวกัน
Yugal Jindle

Yugal ถ้าคุณใช้ MooTools ล่ะ? Qooxdoo? อะไรที่ไม่ใช่ jQuery? RequireJS ไม่ได้แต่งงานกับ jQuery แม้ว่าพวกเขาจะทำงานร่วมกันได้ดีจริงๆ
Gert Sønderโดย

6

การตอบสัญลักษณ์แสดงหัวข้อย่อยของคุณตามลำดับที่ปรากฏ:

  • ทั้งสองทำสิ่งเดียวกันให้สำเร็จ
  • หากคุณมีการจองเกี่ยวกับ jquery ด้วยเหตุผลใดก็ตามให้ใช้ domReady
  • ถูกต้องดังนั้นเพียงใช้ jQuery
  • เพราะไม่ใช่ทุกคนที่ใช้ jQuery
  • ฉันยอมรับเพียงแค่ใช้ jQuery
  • ปลั๊กอินตามคำจำกัดความ 'ฟีดความต้องการ'
  • ajax ข้ามเบราว์เซอร์ไม่ใช่สิ่งที่ ข้ามโดเมน? อาจมีและถ้าไม่มีก็ไม่จำเป็นต้องให้อาหาร
  • , -, -, - ตกลง

เมื่อพูดถึงเรื่องนี้คุณกำลังคิดเรื่องนี้มากเกินไป มันเป็นกลไกในการเรียกใช้งานจาวาสคริปต์บน domReady หากคุณไม่มี jQuery ฉันจะสนับสนุนปลั๊กอิน domReady เนื่องจากคุณมี jQuery อย่าโหลดสคริปต์เพิ่มเติมเพื่อทำบางสิ่งที่มีอยู่แล้ว

การปรับปรุงความชัดเจน

ปลั๊กอิน domReady รวบรวมฟังก์ชันที่จะโทรเมื่อเอกสาร 'พร้อม' หากโหลดแล้วจะดำเนินการทันที

JQuery รวบรวมฟังก์ชันและผูกอ็อบเจ็กต์ที่รอการตัดบัญชีเข้ากับ dom ที่ 'พร้อม' เมื่อโดมพร้อมแล้ววัตถุที่รอการตัดบัญชีจะได้รับการแก้ไขและฟังก์ชันจะเริ่มทำงาน หากโดมนั้น 'พร้อมใช้งาน' อยู่แล้วการเลื่อนเวลาจะได้รับการแก้ไขแล้วดังนั้นฟังก์ชันจะทำงานทันที

ซึ่งหมายความว่าพวกเขาทำสิ่งเดียวกันได้อย่างมีประสิทธิภาพ


0

หลังจากทดลองใช้ requirejs กับหลายโมดูลฉันขอแนะนำให้ใช้domReady domReady

ฉันสังเกตเห็นว่าฟังก์ชันที่เกี่ยวข้องกับ$ (document) .ready (... )ไม่ถูกเรียกใช้เมื่อโหลดโมดูลหลายโมดูลโดย requirejs ฉันสงสัยว่า dom กำลังเตรียมพร้อมก่อนที่จะเรียกใช้โค้ด requirejs ทั้งหมดและ jquery ready callback handler ถูกเรียกก่อนที่จะถูกผูกไว้กับฟังก์ชันที่ผู้ใช้กำหนดเช่นภายในโค้ดโมดูลหลัก

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จะทำงานทันที
Danyal Aytekin

-1

ฉันพบว่าฉันทำสิ่งนี้เป็นส่วนหนึ่งของรายการหลักเพื่อให้จาวาสคริปต์ทั้งหมดของฉันได้รับการรับรองว่า 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');
        });
    });
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.