Plugin yêu cầu domReady so với Jquery $ (tài liệu) .ready ()?


100

Tôi đang sử dụng RequestJS và cần khởi tạo một thứ gì đó trên DOM đã sẵn sàng. Bây giờ, RequestJS cung cấp domReadyplugin , nhưng chúng tôi đã có jQuery $(document).ready(), có sẵn cho tôi vì tôi yêu cầu jQuery.

Vì vậy, tôi có hai lựa chọn:

  1. Sử dụng domReadyplugin:

    require(['domReady'], function (domReady) {
        domReady(function () {
            // Do my stuff here...
        });
    });
  2. Sử dụng $(document).ready():

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

Tôi nên chọn cái nào, và tại sao?

Cả hai tùy chọn dường như hoạt động như mong đợi. Tôi không tự tin vào jQuery của bởi vì RequiJS đang làm điều kỳ diệu của nó; nghĩa là, vì RequiJS sẽ tự động thêm các tập lệnh, tôi lo rằng DOM sẵn sàng có thể xảy ra trước khi tất cả các tập lệnh được yêu cầu động được tải. Trong khi đó, RequestJS sẽ thêm gánh nặng về JS bổ sung chỉ domReadykhi tôi đã có yêu cầu jQuery.

Câu hỏi

  • Tại sao RequestJS cung cấp một domReadyplugin khi chúng ta có thể có jQuery $(document).ready();? Tôi không thấy bất kỳ lợi thế nào của việc bao gồm một phụ thuộc khác.
  • Nếu nó chỉ để đáp ứng nhu cầu, thì tại sao không cung cấp một cái cho AJAX trên nhiều trình duyệt?

Theo như tôi biết, một mô-đun yêu cầu domReadysẽ không được tìm nạp hoặc thực thi sau khi tài liệu đã sẵn sàng và bạn cũng có thể thực hiện tương tự với yêu cầu jQuery:

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

Để rõ ràng hơn về câu hỏi của tôi: sự khác biệt giữa yêu cầu domReadyhoặc là jQuerygì?


4
I am not confident in jquery's dom readytôi muốn đánh dấu nó như là tấn công:p
Dakait

3
dom sẵn sàng của jQuery hoàn toàn đáng tin cậy, ngay cả trên IE. Hàng triệu người sử dụng nó mỗi ngày mà không biết ;-)
John Dvorak

1
Bạn có kiểm soát được vị trí của scriptcác thẻ của mình hay bạn đang viết một thư viện / trình cắm mà người khác sẽ sử dụng (và do đó, họ kiểm soát vị trí của các scriptthẻ trong phần đánh dấu)?
TJ Crowder

3
Ôi trời .. đọc với bối cảnh đầy đủ. I am not confident in jquery's dom ready because requirejs is doing its magic.Vì, request đang đóng gói jquery trong phạm vi cục bộ hạn chế. Đó không phải là vấn đề. (theo như câu hỏi có liên quan).
Yugal Jindle

1
Cảm ơn, @TJCrowder đã chỉnh sửa.
Yugal Jindle

Câu trả lời:


91

Có vẻ như tất cả các điểm chính đều đã bị bắn trúng, nhưng một vài chi tiết đã lọt qua các vết nứt. Chủ yếu:

domReady

Nó vừa là một plugin vừa là một mô-đun. Nếu bạn đưa nó vào mảng yêu cầu w / a theo sau, !mô-đun của bạn sẽ không thực thi cho đến khi nó "an toàn" để tương tác với w / DOM:

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

Lưu ý rằng tải và thực thi là khác nhau; bạn muốn tất cả các tệp của mình tải càng sớm càng tốt, đó là việc thực thi các nội dung nhạy cảm về thời gian.

Nếu bạn bỏ qua !, thì đó chỉ là một mô-đun bình thường trở thành một hàm, có thể nhận lệnh gọi lại không thực thi trước khi DOM an toàn để tương tác với:

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

Lợi thế khi sử dụng domReady làm plugin

Mã phụ thuộc vào mô-đun mà đến lượt nó phụ thuộc vào domReady!có một lợi thế rất đáng kể: Nó không cần phải đợi DOM sẵn sàng!

Giả sử rằng chúng ta có một khối mã, A, phụ thuộc vào một mô-đun, B, phụ thuộc vào domReady!. Mô-đun B sẽ không tải xong trước khi DOM sẵn sàng. Đổi lại, A sẽ không chạy trước khi B đã tải.

Nếu bạn sử dụng domReadynhư một mô-đun thông thường trong B, thì A cũng cần phải phụ thuộc vào domReady, cũng như gói mã của nó bên trong một domReady()lời gọi hàm.

Hơn nữa, điều này có nghĩa là domReady!tận hưởng cùng một lợi thế hơn $(document).ready().

Nêu lại sự khác biệt giữa domReady và $ (document) .ready ()

Cả hai đều tìm hiểu xem / khi nào DOM đã sẵn sàng về cơ bản theo cùng một cách.

Sợ jQuery kích hoạt sai thời điểm

jQuery sẽ kích hoạt mọi lệnh gọi lại sẵn sàng ngay cả khi DOM tải trước khi jQuery thực hiện (mã của bạn không nên quan tâm điều gì xảy ra trước.).


1
Đẹp, đây là những gì tôi đang tìm kiếm. Hợp lý, được hỗ trợ tốt.
Yugal Jindle

Rất vui vì tôi có thể giúp :-)
fncomp

@YugalJindle Có thiếu thứ gì cho tiền thưởng không? :)
fncomp Ngày

Tôi chỉ đang kiểm tra những gì bạn đã viết - của bạn đây!
Yugal Jindle

Nhìn vào mã plugin domReady ( github.com/requirejs/domReady/blob/master/domReady.js ) Tôi không thấy lý do gì khiến bạn cần tải nó là 'domReady!' thay vì 'domReady' - bạn có thể chỉ cho tôi đoạn mã gây ra sự thay đổi trong hành vi không?
Jez

20

Cố gắng trả lời câu hỏi chính của bạn:

Tại sao lại requirejscung cấp domReadyplugin khi chúng ta có thể có jquery $(document).ready();?

Họ thực sự làm hai việc khác nhau. Sự domReadyphụ thuộc của RequestJS biểu thị rằng mô-đun này yêu cầu DOM phải được tải hoàn toàn trước khi có thể chạy (và do đó có thể được tìm thấy trong bất kỳ số lượng mô-đun nào trong ứng dụng của bạn nếu bạn muốn), trong khi $(document).ready()thay vào đó kích hoạt các chức năng gọi lại của nó khi DOM tải xong.

Sự khác biệt có vẻ tinh tế, nhưng hãy nghĩ về điều này: Tôi có một mô-đun cần được kết hợp với DOM theo một cách nào đó, vì vậy tôi có thể dựa vào domReadyvà ghép nối nó vào thời điểm xác định mô-đun hoặc đặt một mô-đun $(document).ready()ở cuối nó với một lệnh gọi lại một hàm init cho mô-đun. Tôi gọi cách tiếp cận đầu tiên là sạch hơn.

Trong khi đó, nếu tôi có một sự kiện cần diễn ra ngay khi DOM đã sẵn sàng, thì $(document).ready()sự kiện đó sẽ là sự kiện bắt đầu, vì điều đó không phụ thuộc cụ thể vào việc RequestJS được thực hiện tải các mô-đun, miễn là các phụ thuộc của mã bạn đang gọi nó từ được đáp ứng.

Cũng đáng xem xét rằng bạn không nhất thiết phải sử dụng RequestJS với jQuery. Bất kỳ mô-đun thư viện nào cần truy cập DOM (nhưng không dựa vào jQuery) thì vẫn hữu ích bằng cách sử dụng domReady.


domReadykhông phải là một sự phụ thuộc cho requestjs. Nó sẽ là một phụ thuộc cho mã nếu bạn đang sử dụng domReadycho sự kiện DocumentReady. Thêm vào đó bạn có vẻ khó hiểu.
Yugal Jindle

1
Câu trả lời tuyệt vời và một gợi ý quan trọng cho sự tinh tế mà nhiều nhà phát triển thường không nhận ra (kể cả tôi ;-)).
Golo Roden

1
Yugal, tôi đã đề cập đến domReadynhư một phụ thuộc, bởi vì đó là cách nó được sử dụng. Không phải là một phần phụ thuộc của RequestJS, mà là của mô-đun nơi nó được sử dụng. Có lẽ tôi nên làm rõ hơn điều đó trong văn bản của mình, bạn có gợi ý về cách làm không?
Gert Sønderby

Vui lòng xem Update2 về câu hỏi. Có thể chúng ta không ở trên cùng một trang.
Yugal Jindle

Yugal, nếu bạn sử dụng MooTools thì sao? Qooxdoo? Bất cứ điều gì không phải jQuery? RequestJS không kết hôn với jQuery, mặc dù họ phải thừa nhận rằng họ làm việc rất tốt với nhau.
Gert Sønderby

6

Trả lời các gạch đầu dòng của bạn theo thứ tự xuất hiện:

  • Cả hai đều hoàn thành cùng một điều
  • Nếu bạn đặt trước về jquery vì bất kỳ lý do gì thì hãy sử dụng domReady
  • Chính xác, vì vậy chỉ cần sử dụng jQuery
  • Bởi vì không phải ai cũng sử dụng jQuery
  • Tôi đồng ý, chỉ cần sử dụng jQuery
  • Các plugin theo định nghĩa 'nguồn cấp dữ liệu cần thiết'.
  • Cross Browser ajax không phải là một thứ. Tên miền chéo? Có lẽ là có, và nếu không có thì không cần cho ăn.
  • , -, -, - Đồng ý

Khi nói đến nó, bạn đang suy nghĩ quá nhiều về điều này. Đó là một cơ chế để thực thi javascript trên domReady. Nếu bạn không có jQuery, tôi sẽ ủng hộ plugin domReady. Vì bạn có jQuery nên không cần tải thêm các tập lệnh để thực hiện một cái gì đó đã có sẵn.

Cập nhật rõ ràng

Plugin domReady thu thập các hàm để gọi khi tài liệu 'sẵn sàng'. Nếu nó đã được tải thì chúng sẽ thực thi ngay lập tức.

JQuery thu thập các hàm và liên kết một đối tượng hoãn lại với dom là 'sẵn sàng'. Khi dom đã sẵn sàng, đối tượng trì hoãn sẽ được giải quyết và các chức năng sẽ kích hoạt. Nếu dom đã 'sẵn sàng' thì sự trì hoãn sẽ đã được giải quyết nên hàm sẽ thực thi ngay lập tức.

Điều này có nghĩa là họ thực hiện chính xác những điều tương tự.


0

Sau một số thử nghiệm với requestj với nhiều mô-đun, tôi khuyên bạn nên sử dụng domReady .

Tôi nhận thấy rằng hàm được liên kết với $ (tài liệu) .ready (...) không được gọi khi nhiều mô-đun được tải bởi requestjs. Tôi nghi ngờ rằng dom đã sẵn sàng trước khi tất cả mã lệnh requestjs được thực thi và trình xử lý lệnh gọi lại sẵn sàng jquery được gọi trước khi nó bị ràng buộc với chức năng do người dùng xác định tức là trong mã mô-đun chính.

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
Tôi nghi ngờ điều đó, Nếu bạn có tất cả các mô-đun trong danh sách phụ thuộc của mình thì tất cả sẽ được tìm nạp và đưa vào bộ nhớ. đăng rằng jquery thu thập các thể hiện dom.ready trước khi thực thi.
Yugal Jindle

Nếu DOM đã sẵn sàng, lệnh gọi lại cho $(document).readysẽ chạy ngay lập tức.
Danyal Aytekin

-1

Tôi thấy rằng tôi thực hiện việc này như một phần của mục nhập chính để tất cả javascript của tôi được đảm bảo rằng DOM đã sẵn sàng và jquery được tải. Không chắc điều này tuyệt vời như thế nào vì vậy hãy hoan nghênh mọi phản hồi nhưng đây là main.js của tôi:

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');
        });
    });
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.