Sự khác biệt giữa `on` và` live` hay` bind` là gì?


172

Trong jQuery v1.7, một phương thức mới, onđã được thêm vào. Từ tài liệu:

Phương thức .on () gắn các trình xử lý sự kiện vào tập hợp các phần tử hiện được chọn trong đối tượng jQuery. 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. '

Sự khác biệt với livevà là bindgì?



Đã tìm kiếm một cái gì đó như thế trước khi yêu cầu và không thành công. Cảm ơn!
Diego

Câu trả lời:


329

on()là một nỗ lực để hợp nhất hầu hết các hàm liên kết sự kiện của jQuery thành một. Đây có thêm tiền thưởng của quét dọn những không hiệu quả với livevs delegate. Trong các phiên bản tương lai của jQuery, các phương thức này sẽ bị xóa và chỉ ononesẽ bị bỏ lại.

Ví dụ:

// Using live()
$(".mySelector").live("click", fn);

// Equivalent `on` (there isn't an exact equivalent, but with good reason)
$(document).on("click", ".mySelector", fn);
// Using bind()
$(".mySelector").bind("click", fn);

// Equivalent `on`
$(".mySelector").on("click", fn);
// Using delegate()
$(document.body).delegate(".mySelector", "click", fn);

// Equivalent `on`
$(document.body).on("click", ".mySelector", fn);

Trong nội bộ, jQuery ánh xạ tất cả các phương thức này các trình xử lý sự kiện tốc ký vào on()phương thức, hơn nữa chỉ ra rằng bạn nên bỏ qua các phương thức này từ bây giờ và chỉ sử dụng on:

bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
},
live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
},
delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
},

Xem https://github.com/jquery/jquery/blob/1.7/src/event.js#L965 .


Như @JamWaffles đã nói câu trả lời dễ hiểu nhất. Bạn có thể vui lòng thêm so sánh giữa trên và đại biểu để hoàn thành câu trả lời? Cảm ơn!
Diego

Xin chào, bạn đã thêm nguồn jquery 4 giây trước tôi: D btw bối cảnh tương đương trực tiếp là tài liệu, không phải tài
liệu.body

1
Thay vào đó, bạn có thể muốn tham khảo thẻ 1.7, nếu không các thay đổi trong tương lai có thể khiến liên kết của bạn không hợp lệ (không trỏ đến đúng vị trí): github.com/jquery/jquery/blob/1.7/src/event.js#L965
Felix Kling

3
$(document.body).delegate("click", ".mySelector", fn);nên là$(document.body).delegate(".mySelector", "click", fn);
Sonny

2
@dsdsdsdsd, tắt đóng vai trò thay thế chung cho unbind, unive và undelegate.
Andy E

12

onlà trong tự nhiên rất gần delegate. Vậy tại sao không sử dụng đại biểu? Đó là bởi vì onkhông đến một mình. có off, để hủy liên kết sự kiện và onetạo một sự kiện chỉ được thực hiện một lần. Đây là một "gói" sự kiện mới.

Vấn đề chính livelà nó gắn vào "cửa sổ", buộc một sự kiện nhấp (hoặc sự kiện khác) vào một phần tử nằm sâu bên trong cấu trúc trang (dom), để "nổi bong bóng" lên đầu trang để tìm sự kiện xử lý sẵn sàng để đối phó với nó. Ở mỗi cấp độ, tất cả các trình xử lý sự kiện phải được kiểm tra, điều này có thể tăng lên nhanh chóng, nếu bạn thực hiện việc nhập sâu ( <body><div><div><div><div><table><table><tbody><tr><td><div><div><div><ul><li><button> etc etc etc...)

Vì vậy, bindnhư click, giống như các chất kết dính sự kiện phím tắt khác gắn trực tiếp vào mục tiêu sự kiện. Nếu bạn có một bảng, giả sử, 1000 dòng và 100 cột và mỗi ô trong số 100.000 ô bao gồm một hộp kiểm mà bạn muốn xử lý. Việc đính kèm 100.000 bộ xử lý sự kiện sẽ mất rất nhiều thời gian khi tải trang. Tạo một sự kiện duy nhất ở cấp độ bảng và sử dụng ủy nhiệm sự kiện là một số đơn đặt hàng có cường độ hiệu quả hơn. Mục tiêu sự kiện sẽ được lấy tại thời điểm thực hiện sự kiện. " this" sẽ là bảng, nhưng " event.target" sẽ là thông thường của bạn " this" trong một clickhàm. Bây giờ, điều tuyệt vời onlà " this" sẽ luôn là mục tiêu sự kiện, và không phải là thùng chứa mà nó được đính kèm.


Không đại biểu đi kèm với undelegate?
DaveWalley

1
Vâng đốm tốt. Bạn học hàng ngày;) (Tài liệu đã được cải thiện rất nhiều kể từ năm 2011)
roselan

5

với .onphương pháp có thể làm .live, .delegate.bindvới chức năng tương tự nhưng với .live()chỉ.live() là có thể (ủy thác các sự kiện để tài liệu).

jQuery("#example").bind( "click", fn ) = = jQuery( "#example").on( "click", fn );

jQuery("#example").delegate( ".examples", "click", fn ) = = jQuery( "#example" ).on( "click", ".examples", fn )

jQuery("#example").live( fn ) = = jQuery( document ).on( "click", "#example", fn )

Tôi có thể xác nhận điều này trực tiếp từ nguồn jQuery:

bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
},

live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
},

delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
},

jQuery (this.context)? this.context=== documenttrong hầu hết các trường hợp


3

(Câu mở đầu của tôi có ý nghĩa hơn trước khi bạn thay đổi câu hỏi. Ban đầu bạn nói "Sự khác biệt với livecái gì?")

ongiống như delegatenó giống như live, về cơ bản nó là một dạng thống nhất binddelegate(trên thực tế, nhóm nghiên cứu cho biết mục đích của nó là "... để thống nhất tất cả các cách gắn sự kiện vào tài liệu ..." ).

livevề cơ bản on(hoặc delegate) gắn liền với tài liệu nói chung. Nó không được chấp nhận kể từ v1.7 theo hướng sử dụng onhoặc delegate. Đi về phía trước, tôi nghi ngờ chúng ta sẽ thấy mã onchỉ sử dụng , thay vì sử dụng bindhoặc delegate(hoặc live) ...

Vì vậy, trong thực tế, bạn có thể:

  1. Sử dụng onnhư bind:

    /* Old: */ $(".foo").bind("click", handler);
    /* New: */ $(".foo").on("click", handler);
  2. Sử dụng onlike delegate(ủy nhiệm sự kiện bắt nguồn từ một yếu tố nhất định):

    /* Old: */ $("#container").delegate(".foo", "click", handler);
    /* New: */ $("#container").on("click", ".foo", handler);
  3. Sử dụng onlike live(ủy nhiệm sự kiện bắt nguồn từ tài liệu):

    /* Old: */ $(".foo").live("click", handler);
    /* New: */ $(document).on("click", ".foo", handler);

1
Trong trang tôi đã liên kết có nội dung "Nếu HTML mới được đưa vào trang, hãy chọn các thành phần và đính kèm trình xử lý sự kiện sau khi HTML mới được đặt vào trang. Hoặc, sử dụng các sự kiện được ủy quyền để đính kèm trình xử lý sự kiện, như được mô tả tiếp theo." . Vì vậy, có nhiều khả năng ràng buộc, không sống. Tôi có đúng không
Diego

@Diego: onlà sự kết hợp của binddelegate, như tôi đã nói, không giống lắm live. Bạn có thể sử dụng onlike bind(đính kèm trình xử lý trực tiếp vào một phần tử) hoặc bạn có thể sử dụng onlike delegate(đính kèm trình xử lý vào một phần tử, nhưng chỉ kích hoạt sự kiện nếu phần tử thực tế được nhấp khớp với bộ chọn và như thể phần tử đó là một phần tử sự kiện đã xảy ra vào - ví dụ: ủy nhiệm sự kiện) hoặc bạn có thể sử dụng nó như thế nào live( delegatesử dụng tài liệu làm gốc). Đó là phái đoàn sự kiện làm cho nó hữu ích nếu bạn thêm các yếu tố một cách linh hoạt.
TJ Crowder

1
live cũ cũng có thể được sử dụng như đại biểu: $("#id", ".class").live(fn)= $(".class").delegate("#id", fn );Trên thực tế trong nguồn jQuery cũ, họ đã sử dụng live như trường hợp chung và ủy nhiệm như một trường hợp đặc biệt, điều này khiến mọi thứ trở nên khó hiểu hơn khi bạn nghĩ về nó.
Esailija

@Esailija: Đủ công bằng. Tôi không nghĩ rằng đó là việc sử dụng nó được biết đến, bởi vì họ đã thêm delegatenhanh chóng, nhưng vẫn còn. :-)
TJ Crowder


2

Không có cái nào cho trường hợp sử dụng cơ bản. Hai dòng này có chức năng giống nhau

$( '#element' ).bind( 'click', handler );
$( '#element' ).on( 'click', handler );

.on () cũng có thể thực hiện ủy nhiệm sự kiện và được ưu tiên.

.bind () thực sự chỉ là một bí danh cho .on (). Đây là định nghĩa của hàm liên kết trong 1.7.1

bind: function( types, data, fn ) {
return this.on( types, null, data, fn );
},

Ý tưởng để thêm .on () là tạo API sự kiện hợp nhất, thay vì có nhiều chức năng cho sự kiện ràng buộc; .on () thay thế .bind (), .live () và .delegate ().


0

Một cái gì đó bạn cần lưu ý nếu bạn muốn có các trình xử lý sự kiện liên quan đến phần tử - chú ý phần tử mà trình xử lý được đính kèm!

Ví dụ: nếu bạn sử dụng:

$('.mySelector').bind('click', fn);

bạn sẽ nhận được các trình xử lý sự kiện bằng cách sử dụng:

$('.mySelector').data('events');

Nhưng nếu bạn sử dụng:

$('body').on('click', '.mySelector', fn);

bạn sẽ nhận được các trình xử lý sự kiện bằng cách sử dụng:

$('body').data('events');

(trong trường hợp cuối cùng, đối tượng sự kiện có liên quan sẽ có bộ chọn = ". mySelector")


eventsdù sao cũng không có giấy tờ và tôi nghĩ nó không còn hoạt động trong 1.9
John Dvorak

Đúng. Người ta có thể sử dụng _data thay vì dữ liệu trong các phiên bản mới hơn. Câu trả lời là về sự khác biệt trong "chủ sở hữu sự kiện" thay vì cú pháp chính xác cho các phiên bản cũ hoặc mới. Có các bài viết khác về cú pháp chính xác cho các phiên bản JQuery khác nhau. Ví dụ: stackoverflow.com/questions/2518421/NH
Alexander
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.