Sự khác biệt giữa .on ('click') so với .click ()


526

Có sự khác biệt giữa các mã sau đây?

$('#whatever').on('click', function() {
     /* your code here */
});

$('#whatever').click(function() {
     /* your code here */
});

Câu trả lời:


761

Tôi nghĩ rằng, sự khác biệt là trong mô hình sử dụng.

Tôi thích .onhơn .clickvì trước đây có thể sử dụng ít bộ nhớ hơn và làm việc cho các yếu tố được thêm động.

Hãy xem xét các html sau:

<html>
    <button id="add">Add new</button>
    <div id="container">
        <button class="alert">alert!</button>
    </div>
</html>

nơi chúng tôi thêm các nút mới thông qua

$("button#add").click(function() {
    var html = "<button class='alert'>Alert!</button>";
    $("button.alert:last").parent().append(html);
});

và muốn "Thông báo!" để hiển thị một cảnh báo. Chúng ta có thể sử dụng "nhấp chuột" hoặc "bật" cho điều đó.


Khi chúng ta sử dụng click

$("button.alert").click(function() {
    alert(1);
});

với ở trên, một trình xử lý riêng biệt được tạo cho mỗi phần tử phù hợp với bộ chọn. Điều đó có nghĩa là

  1. nhiều yếu tố phù hợp sẽ tạo ra nhiều trình xử lý giống hệt nhau và do đó làm tăng dung lượng bộ nhớ
  2. các mục được thêm động sẽ không có trình xử lý - tức là, trong html ở trên, "Thông báo!" mới được thêm vào các nút sẽ không hoạt động trừ khi bạn khởi động lại trình xử lý.

Khi chúng ta sử dụng .on

$("div#container").on('click', 'button.alert', function() {
    alert(1);
});

với phần trên, một trình xử lý duy nhất cho tất cả các phần tử khớp với bộ chọn của bạn, bao gồm các phần tử được tạo động.


... một lý do khác để sử dụng .on

Như Adrien bình luận dưới đây, một lý do khác để sử dụng .onlà các sự kiện được đặt tên.

Nếu bạn thêm một trình xử lý với .on("click", handler)bạn, thường loại bỏ nó .off("click", handler)sẽ loại bỏ trình xử lý đó. Rõ ràng điều này chỉ hoạt động nếu bạn có một tham chiếu đến hàm, vậy nếu bạn không có thì sao? Bạn sử dụng không gian tên:

$("#element").on("click.someNamespace", function() { console.log("anonymous!"); });

không ràng buộc thông qua

$("#element").off("click.someNamespace");

2
Điều gì về: $ ('button.alert'). On ('click', function () {alert (1);}); ?
Matthew

8
@andreister: sửa lỗi cho tôi nếu tôi sai nhưng tôi tin rằng một lợi thế khác là việc sử dụng các không gian tên khi sử dụng on('click' ...), xem stackoverflow.com/a/3973060/759452 tức là. on('click.darkenallothersections' ...)và đồng thời on('click.displaynextstep' ...), sau đó tôi chỉ có thể hủy liên kết với người tôi chọn sử dụng.unbind('click.displaynextstep')
Adrien Be

Tôi không nghĩ rằng một trình xử lý riêng biệt được tạo cho mọi phần tử phù hợp với bộ chọn. Tôi nghĩ rằng 1 trình xử lý sẽ được tạo, nhưng chi phí xuất phát từ việc ràng buộc trình xử lý này với nhiều yếu tố và giám sát tất cả các yếu tố này. Ít nhất, tôi đã không tìm thấy điều này trong tài liệu.
Truy tìm

7
Bất cứ ai có thể giải thích tại sao .on có thể làm việc cho mục được thêm động nhưng .click không thể?
MạnhT

2
on()là xu hướng trong jQuery. Tôi đã phải cập nhật $(window).load(function() {});lên $(window).on("load", function (e) {})khi tôi nâng cấp lên jQuery 3.
Victor Stoddard

37

Có sự khác biệt giữa các mã sau đây?

Không, không có sự khác biệt về chức năng giữa hai mẫu mã trong câu hỏi của bạn. .click(fn)là một "phương pháp phím tắt" cho .on("click", fn). Từ tài liệu cho.on() :

Có các phương pháp tốc ký cho một số sự kiện như .click()có thể được sử dụng để đính kèm hoặc kích hoạt trình xử lý sự kiện. Để biết danh sách đầy đủ các phương pháp tốc ký, hãy xem danh mục sự kiện .

Lưu ý rằng .on()khác với .click()ở chỗ nó có khả năng tạo các trình xử lý sự kiện được ủy nhiệm bằng cách truyền selectortham số, trong khi .click()không. Khi .on()được gọi mà không có selectortham số, nó hoạt động giống hệt như .click(). Nếu bạn muốn đoàn sự kiện, sử dụng .on().


4
Điều gì về vấn đề hiệu suất đã chỉ ra @andreister của tôi?
rubo77

@ rubo77 không đáng kể ở mức tốt nhất. Chúng tôi đang dùng một phần nghìn giây.
Rory McCrossan

1
@RoryMcCrossan đó là một vấn đề lớn đối với tôi - Tôi đang tìm kiếm điều này bởi vì tôi có tới 3000 câu hỏi trên một trang cần các sự kiện. Mỗi milisec làm cho trang của tôi mất 3 giây để thực hiện. Nhận xét của bạn không hữu ích cho danh sách lớn.
Randy

11
Vấn đề lớn hơn là tại sao bạn có 3000 câu hỏi trên một trang. Nếu bạn theo mô hình UI tốt, bạn sẽ không bao giờ có nhiều thông tin trên một trang. Nhìn vào phân trang, hoặc lười tải. Ngay cả việc sử dụng ủy nhiệm sự kiện để có một trình xử lý sự kiện duy nhất cho tất cả các yếu tố đó sẽ tốt hơn.
Rory McCrossan

5
@ rubo77 - Hiệu suất đạt được chỉ được nhìn thấy khi sử dụng phân quyền sự kiện bằng cách truyền selectortham số. Nếu bạn gọi .on()mà không có selectortham số thì không có cải thiện hiệu suất so với sử dụng .click().
gilly3

23

.on()là cách được đề xuất để thực hiện tất cả các ràng buộc sự kiện của bạn kể từ jQuery 1.7. Nó cuộn tất cả các chức năng của cả hai .bind().live()thành một chức năng thay đổi hành vi khi bạn truyền cho nó các tham số khác nhau.

Như bạn đã viết ví dụ của bạn, không có sự khác biệt giữa hai. Cả hai ràng buộc một xử lý cho clicksự kiện #whatever. on()cung cấp thêm tính linh hoạt trong việc cho phép bạn ủy thác các sự kiện do trẻ em của #whatevermột chức năng xử lý duy nhất, nếu bạn chọn.

// Bind to all links inside #whatever, even new ones created later.
$('#whatever').on('click', 'a', function() { ... });

"Liên kết với tất cả các liên kết bên trong #whthing, ngay cả những liên kết mới được tạo sau này." Đó không phải là chính xác những gì .live()không? Ngoài ra, điều này dường như mâu thuẫn với các câu trả lời khác nói rằng nó chỉ có chức năng của .click(), và do đó không áp dụng cho các sự kiện trong tương lai.
bgcode

3
@babonk - Điều này không mâu thuẫn với câu trả lời khác, bởi vì như Interrobang nói trong đoạn đầu tiên .on()có thể làm những gì .click()làm làm những gì .bind().live()làm - nó phụ thuộc những gì thông số bạn gọi nó với. (Một số câu trả lời khác cũng đề cập đến vấn đề này.) Lưu ý rằng "Liên kết với tất cả các liên kết bên trong #whthing" không phải là cái gì .live(), nó là cái gì .delegate(). .live()liên kết với tất cả bên trong documentchứ không phải để bạn chỉ định container. Lưu ý cũng .live()không được chấp nhận từ jQuery 1.7 trở đi.
nnnnnn

+1 cho các sự kiện được ủy nhiệm: "Bằng cách chọn một yếu tố được đảm bảo có mặt tại thời điểm trình xử lý sự kiện được ủy quyền được đính kèm, bạn có thể sử dụng các sự kiện được ủy nhiệm để tránh phải thường xuyên đính kèm và xóa trình xử lý sự kiện." api.jquery.com/on
jimasp

19

Như được đề cập bởi các câu trả lời khác:

$("#whatever").click(function(){ });
// is just a shortcut for
$("#whatever").on("click", function(){ })

Lưu ý rằng mặc dù .on()hỗ trợ một số kết hợp tham số khác .click()không có, cho phép nó xử lý phân quyền sự kiện (thay thế .delegate().live()).

(Và rõ ràng có các phương pháp phím tắt tương tự khác cho "keyup", "tập trung", v.v.)

Lý do tôi đăng một câu trả lời bổ sung là để đề cập đến những gì xảy ra nếu bạn gọi .click()mà không có tham số:

$("#whatever").click();
// is a shortcut for
$("#whatever").trigger("click");

Lưu ý rằng nếu bạn sử dụng .trigger()trực tiếp, bạn cũng có thể truyền các tham số bổ sung hoặc đối tượng sự kiện jQuery, điều mà bạn không thể làm với .click().

Tôi cũng muốn đề cập rằng nếu bạn nhìn vào mã nguồn jQuery (trong jquery-1.7.1.js), bạn sẽ thấy rằng bên trong hàm .click()(hoặc .keyup(), v.v.) sẽ thực sự gọi .on()hoặc .trigger(). Rõ ràng điều này có nghĩa là bạn có thể yên tâm rằng chúng thực sự có kết quả tương tự, nhưng điều đó cũng có nghĩa là việc sử dụng .click()có thêm một chút chi phí - không phải lo lắng hay thậm chí nghĩ về hầu hết các trường hợp, nhưng về mặt lý thuyết nó có thể quan trọng trong những trường hợp đặc biệt.

EDIT: Cuối cùng, lưu ý .on()cho phép bạn liên kết một số sự kiện với cùng một chức năng trong một dòng, ví dụ:

$("#whatever").on("click keypress focus", function(){});

Cả hai phương thức đều được tải trong bộ nhớ để sử dụng? Vì vậy, nó không thành vấn đề? Và để dễ đọc nó có thể xử lý hơn?
Vince V.

@VinceV. - Đúng. Đối với các trình xử lý sự kiện không được ủy quyền "tiêu chuẩn", cả hai phương thức đều làm điều tương tự và sự khác biệt về hiệu suất là không đáng kể, vì vậy phương pháp nào bạn sử dụng thực sự là vấn đề sở thích cá nhân. (Tôi thường chọn .click().)
nnnnnn

9

Không, không có.
Điểm quan trọng on()là sự quá tải khác của nó và khả năng xử lý các sự kiện không có phương pháp phím tắt.


1
@arigold: Đó là những quá tải khác.
SLaks

9

Chúng có vẻ giống nhau ... Tài liệu từ hàm click () :

Phương thức này là lối tắt cho .bind ('click', handler)

Tài liệu từ ngày () :

Kể từ jQuery 1.7, phương thức .on () cung cấp tất cả các chức năng cần thiết để đính kèm các trình xử lý sự kiện. Để được trợ giúp chuyển đổi từ các phương thức sự kiện jQuery cũ hơn, hãy xem .bind (), .delegate () và .live (). Để xóa các sự kiện bị ràng buộc với .on (), hãy xem .off ().


Cả hai quan điểm của bạn nên được hợp nhất. Click () là lối tắt cho .Bind () và .On () ... Theo JQUERY 1.7.0 +, đây cũng là lối tắt cho Trigger ('click'). [ api.jquery.com/click/]
Dhanasekar

Đây là một lời giải thích khá đơn giản từ các tài liệu, nhưng câu trả lời dưới đây có một ví dụ tốt về lý do tại sao một cái tốt hơn cái kia trong .clickvs.on
phatskat

@phatskat - Tôi tình cờ đồng ý với bạn :)
dana

8

.click các sự kiện chỉ hoạt động khi phần tử được kết xuất và chỉ được gắn vào các phần tử được tải khi DOM sẵn sàng.

.on các sự kiện được gắn động với các phần tử DOM, rất hữu ích khi bạn muốn đính kèm một sự kiện vào các phần tử DOM được hiển thị theo yêu cầu ajax hoặc một cái gì đó khác (sau khi DOM đã sẵn sàng).


5

Tại đây bạn sẽ nhận được danh sách các cách khác nhau để áp dụng sự kiện nhấp chuột. Bạn có thể chọn một cách phù hợp là có thể thay đổi hoặc nếu nhấp chuột của bạn không hoạt động, chỉ cần thử một cách khác trong số này.

$('.clickHere').click(function(){ 
     // this is flat click. this event will be attatched 
     //to element if element is available in 
     //dom at the time when JS loaded. 

  // do your stuff
});

$('.clickHere').on('click', function(){ 
    // same as first one

    // do your stuff
})

$(document).on('click', '.clickHere', function(){
          // this is diffrent type 
          //  of click. The click will be registered on document when JS 
          //  loaded and will delegate to the '.clickHere ' element. This is 
          //  called event delegation 
   // do your stuff
});

$('body').on('click', '.clickHere', function(){
   // This is same as 3rd 
   // point. Here we used body instead of document/

   // do your stuff
});

$('.clickHere').off().on('click', function(){ // 
    // deregister event listener if any and register the event again. This 
    // prevents the duplicate event resistration on same element. 
    // do your stuff
})

3

Bây giờ họ đã phản đối click (), vì vậy tốt nhất nên sử dụng ('click')


Vậy bạn sẽ làm gì nếu bạn muốn hành vi click () cũ bây giờ?
bgcode

1

Theo như tìm hiểu từ internet và một số bạn bè .on () được sử dụng khi bạn tự động thêm các yếu tố. Nhưng khi tôi sử dụng nó trong một trang đăng nhập đơn giản, nơi sự kiện nhấp sẽ gửi AJAX đến node.js và khi trả lại các phần tử mới, nó bắt đầu gọi các cuộc gọi đa AJAX. Khi tôi thay đổi nó để bấm () mọi thứ đều ổn. Thật ra tôi không gặp phải vấn đề này trước đây.


0

CÁC YẾU TỐ MỚI

Là một phụ lục cho các câu trả lời toàn diện ở trên để làm nổi bật các điểm quan trọng nếu bạn muốn nhấp để đính kèm với các yếu tố mới:

  1. các phần tử được chọn bởi bộ chọn đầu tiên, ví dụ $ ("body") phải tồn tại tại thời điểm khai báo được thực hiện nếu không có gì để đính kèm.
  2. bạn phải sử dụng ba đối số trong hàm .on () bao gồm bộ chọn hợp lệ cho các thành phần đích của bạn làm đối số thứ hai.

-1
$('.UPDATE').click(function(){ }); **V/S**    
$(document).on('click','.UPDATE',function(){ });

$(document).on('click','.UPDATE',function(){ });
  1. nó hiệu quả hơn $ ('. CẬP NHẬT'). click (function () {});
  2. nó có thể sử dụng ít bộ nhớ hơn và hoạt động cho các yếu tố được thêm động.
  3. đôi khi dữ liệu được tìm nạp động với nút chỉnh sửa và xóa không tạo ra sự kiện JQuery tại thời điểm EDIT HOẶC XÓA DỮ LIỆU dữ liệu hàng theo mẫu, thời gian đó $(document).on('click','.UPDATE',function(){ });hoạt động hiệu quả giống như dữ liệu được tìm nạp bằng cách sử dụng jquery. nút không hoạt động tại thời điểm cập nhật hoặc xóa:

nhập mô tả hình ảnh ở đây


$ (tài liệu) .on ('nhấp', '. CẬP NHẬT', hàm () {}); 1) nó hiệu quả hơn $ ('. CẬP NHẬT'). Click (function () {}); 2) nó có thể sử dụng ít bộ nhớ hơn và hoạt động cho các yếu tố được thêm động. 3) đôi khi dữ liệu được tìm nạp động với nút chỉnh sửa và xóa không tạo ra sự kiện JQuery tại thời điểm EDIT HOẶC XÓA DỮ LIỆU dữ liệu hàng ở dạng, thời điểm đó $ (tài liệu) .on ('click', '. UPDATE', function () {}); là hoạt động hiệu quả. [giống như dữ liệu được tìm nạp bằng cách sử dụng jquery. nút không hoạt động tại thời điểm cập nhật hoặc xóa
Devang Thuê
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.