2009-05-25 27 views
32

Tôi vừa viết hàm $(). Bind ('event') và sau đó lo ngại rằng loại cuộc gọi này có thể rất tốn kém nếu jQuery phải chạy qua từng phần tử trong DOM để ràng buộc sự kiện này.Các sự kiện ràng buộc trong jQuery rất tốn kém hay rất rẻ?

Hoặc có thể, nó chỉ hiệu quả như một sự kiện có thể. Tài liệu jQuery tôi đã đọc không làm rõ điều này. Bạn có ý kiến ​​gì không?

Trả lời

71

Có hai điều có thể làm cho mã ràng buộc sự kiện của bạn chậm: bộ chọn và số lần liên kết. Điều quan trọng nhất trong số hai là số lần kết buộc, nhưng bộ chọn có thể tác động đến hiệu suất ban đầu của bạn.

Theo như bộ chọn đi, chỉ cần đảm bảo bạn không sử dụng bộ chọn tên lớp thuần túy như .myclass. Nếu bạn biết rằng lớp myclass sẽ luôn ở trong một yếu tố <div>, hãy chọn bộ chọn của bạn là div.myclass vì nó sẽ giúp jQuery tìm các phần tử phù hợp nhanh hơn. Ngoài ra, không có advantange của jQuery cho phép bạn cung cấp cho nó chuỗi chọn rất lớn. Tất cả mọi thứ nó có thể làm với bộ chọn chuỗi nó cũng có thể thực hiện thông qua các hàm, và điều này là có chủ ý, vì nó (nhanh chóng thừa nhận) nhanh hơn để làm theo cách này vì jQuery không phải ngồi xung quanh để phân tích chuỗi của bạn để tìm ra cái gì bạn muốn. Vì vậy, thay vì làm $('#myform input:eq(2)'); bạn có thể làm $('input','#myform').eq(2);. Bằng cách xác định một bối cảnh, chúng tôi cũng không làm cho jQuery nhìn bất cứ nơi nào nó không phải, mà là nhanh hơn nhiều. More on this here.

Theo số lượng các ràng buộc: nếu bạn có số lượng phần tử tương đối trung bình thì bạn sẽ ổn - mọi thứ lên tới 200, 300 kết quả yếu tố tiềm năng sẽ hoạt động tốt trong các trình duyệt hiện đại. Nếu bạn có nhiều hơn thế này, bạn có thể muốn thay vào đó hãy xem xét Đoàn đại biểu sự kiện.

Đoàn đại biểu sự kiện là gì? Về cơ bản, khi bạn chạy mã như thế này:

$('div.test').click(function() { 
    doSomething($(this)); 
}); 

jQuery đang làm một cái gì đó như thế này đằng sau hậu trường (ràng buộc một sự kiện cho mỗi yếu tố phù hợp):

$('div.test').each(function() { 
    this.addEventListener('click', function() { 
     doSomething(this); 
    }, false); 
}); 

này có thể nhận được hiệu quả nếu bạn có một số lượng lớn các yếu tố. Với sự kiện phái đoàn, bạn có thể cắt giảm số lượng các ràng buộc thực hiện xuống một. Nhưng bằng cách nào? Đối tượng sự kiện có thuộc tính target cho phép bạn biết yếu tố nào mà sự kiện đó đã tác động. Vì vậy, bạn có thể làm như sau:

$(document).click(function(e) { 
    var $target = $(e.target); 
    if($target.is('div.test')) { // the element clicked on is a DIV 
           // with a class of test 
     doSomething($target); 
    } 
}); 

Rất may là bạn không thực sự phải mã hóa ở trên với jQuery. Hàm live được quảng cáo như một cách dễ dàng để liên kết các sự kiện với các phần tử chưa tồn tại, thực sự có thể thực hiện điều này bằng cách sử dụng ủy quyền sự kiện và kiểm tra tại thời điểm hành động xảy ra nếu mục tiêu khớp với công cụ chọn bạn chỉ định . Điều này có tác dụng phụ, tất nhiên, rất tiện dụng khi tốc độ là quan trọng.

Đạo đức của câu chuyện?Nếu bạn quan ngại về số lượng các ràng buộc, tập lệnh của bạn vừa thay thế .bind bằng .live và đảm bảo bạn có bộ chọn thông minh.

Tuy nhiên, lưu ý rằng không phải tất cả các sự kiện đều được hỗ trợ bởi .live. Nếu bạn cần một cái gì đó không được hỗ trợ bởi nó, bạn có thể kiểm tra các plugin livequery, đó là sống trên steroid.

+1

đây là một câu trả lời tuyệt vời – Jason

+2

Cần lưu ý rằng vì 'đại biểu' đã được thêm vào, có thể cho tập lệnh của bạn thậm chí còn nhanh hơn so với 'sống'. –

+4

Tôi nhận thấy rằng .myClass nhanh hơn div.myClass: http://jsperf.com/div-test-vs-test –

-1

Về cơ bản, bạn sẽ không làm tốt hơn. Tất cả những gì nó đang làm là gọi attachEventListener() trên mỗi phần tử bạn đã chọn.

Chỉ trên thời gian phân tích cú pháp, phương pháp này có thể nhanh hơn thiết lập trình xử lý sự kiện được gạch chân trên mỗi phần tử.

Nói chung, tôi sẽ coi đây là một hoạt động rất rẻ tiền.

Các vấn đề liên quan