jQuery.click () so với onClick


558

Tôi có một ứng dụng jQuery rất lớn và tôi đang sử dụng hai phương thức bên dưới cho các sự kiện nhấp chuột.

Phương pháp đầu tiên

HTML

<div id="myDiv">Some Content</div>

jQuery

$('#myDiv').click(function(){
    //Some code
});

Phương pháp thứ hai

HTML

<div id="myDiv" onClick="divFunction()">Some Content</div>

Gọi hàm JavaScript

function divFunction(){
    //Some code
}

Tôi sử dụng phương pháp thứ nhất hoặc thứ hai trong ứng dụng của mình. Cái nào tốt hơn? Tốt hơn cho hiệu suất? Và chuẩn?


9
Bạn có thể tìm hiểu về các cách khác nhau để đính kèm trình xử lý sự kiện và ưu điểm / nhược điểm của chúng tại đây: quirksmode.org/js/introevents.html . jQuery chỉ là một trình bao bọc đẹp để đăng ký sự kiện nâng cao.
Felix Kling

12
Hãy nhớ đặt chức năng nhấp chuột bên trong $ (tài liệu). Đã (hàm ().
joan16v 17/03/2016

Câu trả lời:


559

Sử dụng $('#myDiv').click(function(){tốt hơn vì nó theo mô hình đăng ký sự kiện tiêu chuẩn. (jQuery sử dụng nội bộaddEventListenerattachEvent).

Về cơ bản đăng ký một sự kiện theo cách hiện đại là cách xử lý các sự kiện không phô trương . Ngoài ra để đăng ký nhiều hơn một người nghe sự kiện cho mục tiêu bạn có thể gọi addEventListener()cho cùng một mục tiêu.

var myEl = document.getElementById('myelement');

myEl.addEventListener('click', function() {
    alert('Hello world');
}, false);

myEl.addEventListener('click', function() {
    alert('Hello world again!!!');
}, false);

http://jsfiddle.net/aj55x/1/

Tại sao nên sử dụng addEventListener? (Từ MDN)

addEventListener là cách để đăng ký một trình lắng nghe sự kiện như được chỉ định trong W3C DOM. Lợi ích của nó là như sau:

  • Nó cho phép thêm nhiều hơn một trình xử lý cho một sự kiện. Điều này đặc biệt hữu ích cho các thư viện DHTML hoặc phần mở rộng Mozilla cần hoạt động tốt ngay cả khi các thư viện / tiện ích mở rộng khác được sử dụng.
  • Nó cho phép bạn kiểm soát tốt hơn giai đoạn khi người nghe được kích hoạt (chụp so với sủi bọt)
  • Nó hoạt động trên mọi phần tử DOM, không chỉ các phần tử HTML.

Tìm hiểu thêm về đăng ký sự kiện hiện đại -> http://www.quirksmode.org/js/events_advified.html

Các phương pháp khác như đặt thuộc tính HTML , ví dụ:

<button onclick="alert('Hello world!')">

Hoặc thuộc tính phần tử DOM , ví dụ:

myEl.onclick = function(event){alert('Hello world');}; 

đã cũ và chúng có thể được viết qua dễ dàng.

Nên tránh thuộc tính HTML vì nó làm cho đánh dấu lớn hơn và ít đọc hơn. Mối quan tâm về nội dung / cấu trúc và hành vi không được phân tách rõ ràng, làm cho một lỗi khó tìm thấy hơn.

Vấn đề với phương thức thuộc tính phần tử DOM là chỉ một trình xử lý sự kiện có thể được liên kết với một phần tử cho mỗi sự kiện.

Tìm hiểu thêm về xử lý sự kiện truyền thống -> http://www.quirksmode.org/js/events_tradmod.html

Tham khảo MDN: https://developer.mozilla.org/en-US/docs/DOM/event


13
Hãy nói rằng bạn chạy $('#myDiv').click(function(){mã trước, sau đó bạn tạo 20 hàng HTML động từ JavaScript và mỗi hàng có một nút trên đó khi nhấp vào JavaScript là bắt buộc để thực hiện cùng chức năng đó. Nếu bạn làm điều đó trước thì nó sẽ không hoạt động vì trình xử lý sự kiện đã được thêm vào trước khi HTML được tạo. Có vẻ dễ dàng hơn khi chỉ cần onclick="functionName()"đưa vào HTML được tạo động sau đó nút này hoạt động ngay lập tức. Hay bạn có biết một giải pháp thanh lịch hơn cho tình huống này?
zuallauz

17
@zuallauz cho trường hợp đó jQuery cung cấp .delegate()chức năng. Nó sẽ đính kèm sự kiện vào bất kỳ yếu tố nào sẽ xuất hiện trong tương lai trên trang web.
Zefiryn

17
@SimonRobb .livekhông được dùng nữa. Sử dụng .delegatecho các phiên bản cũ hơn hoặc sử dụng .oncho các phiên bản jQuery mới hơn.
Selvakumar Arumugam

4
@Vega, Điểm tốt. Còn về khả năng đọc thì sao? Bây giờ bạn phải tìm kiếm tất cả các tệp JS được tham chiếu trên trang để xem tất cả các trình xử lý nhấp chuột của một phần tử theo ID của phần tử thay vì tìm kiếm tên hàm. Bạn nghĩ gì về điều này?
supertonsky

6
Tôi đồng ý với @supertonsky. Tôi hoàn toàn không đồng ý rằng $ ('# myDiv'). Click (function () {là tốt hơn. Trong một ứng dụng javascript lớn liên kết với một sự kiện trở nên khó khăn để tìm tất cả các tham chiếu liên kết với mục tiêu đó. , một id, một đứa trẻ tham chiếu đến thẻ html? Và điều gì xảy ra nếu css thay đổi và tên lớp bạn cần phải thay đổi? Theo kinh nghiệm của tôi khi làm việc với mã người khác, nó trở nên rất xấu rất nhanh.
Jon

65

Để có hiệu suất tốt hơn, hãy sử dụng JavaScript gốc. Để phát triển nhanh hơn, hãy sử dụng jQuery. Kiểm tra sự so sánh về hiệu suất tại jQuery vs Performance Element Performance .

Tôi đã thực hiện một thử nghiệm trong Firefox 16.0 32-bit trên Windows Server 2008 R2 / 7 64-bit

$('span'); // 6,604 operations per second
document.getElementsByTagName('span'); // 10,331,708 operations/sec

Đối với các sự kiện nhấp chuột, hãy kiểm tra các sự kiện Trình duyệt gốc với trình kích hoạt jquery hoặc jQuery vs Liên kết sự kiện nhấp chuột gốc .

Thử nghiệm trong Chrome 22.0.1229.79 32 bit trên Windows Server 2008 R2 / 7 64 bit

$('#jquery a').click(window.testClickListener); // 2,957 operations/second

[].forEach.call( document.querySelectorAll('#native a'), function(el) {
    el.addEventListener('click', window.testClickListener, false);
}); // 18,196 operations/second

9
jQuery nên có thể chạy trong nhiều môi trường khác nhau, điều đó giúp nó dễ dàng hơn và dễ viết hơn, nhưng nếu tốc độ là quan trọng nhất thì jQuery không phải là câu trả lời
Coops

Hãy cẩn thận khi sử dụng forEach vì không phải tất cả trình duyệt đều tương thích, tôi nghĩ không phải là IE. Có lẽ một polyfill sẽ hữu ích.
khaled_webdev

39

Từ những gì tôi hiểu, câu hỏi của bạn không thực sự là có nên sử dụng jQuery hay không. Thay vào đó: Tốt hơn là liên kết các sự kiện nội tuyến trong HTML hoặc thông qua người nghe sự kiện?

Liên kết nội tuyến bị phản đối. Hơn nữa, theo cách này, bạn chỉ có thể liên kết một chức năng với một sự kiện nhất định.

Vì vậy tôi khuyên bạn nên sử dụng trình nghe sự kiện. Bằng cách này, bạn sẽ có thể liên kết nhiều chức năng với một sự kiện duy nhất và hủy liên kết chúng sau này nếu cần. Hãy xem xét mã JavaScript thuần túy này:

querySelector('#myDiv').addEventListener('click', function () {
    // Some code...
});

Điều này hoạt động trong hầu hết các trình duyệt hiện đại.

Tuy nhiên, nếu bạn đã bao gồm jQuery trong dự án của mình - chỉ cần sử dụng jQuery: .onhoặc .clickhàm.


Có thể đăng ký nhiều hàm bằng HTML nội tuyến như <div onclick = "handler1 (); handler2 (); handler3 ();"> </ div>
Kira

2
Bằng cách này, bạn vẫn chỉ đăng ký một "biểu thức". Ví dụ: nếu handler1ném lỗi handler2handler3sẽ không bao giờ được gọi. Hơn nữa, bạn không thể tự động thêm và xóa một số phần mềm nhất định khỏi người nghe. Và cuối cùng nhưng không kém, handler1, handler2handler3đã được khai báo trong phạm vi toàn cầu mà là một mùi.
Michał Miszczyszyn

Sử dụng try..catchbên trong các chức năng sẽ không hoạt động khi handler2không xác định. JavaScript nội tuyến của FYI rõ ràng không hoạt động khi JS bị vô hiệu hóa trong trình duyệt của người dùng, vui lòng không thông tin sai cho người khác.
Michał Miszczyszyn

Tôi đã đề cập rằng tôi không chắc chắn về JavaScript bị vô hiệu hóa. Tôi không thông tin sai hoặc lừa dối người khác
Kira

Trong trường hợp đó, bạn có thể thử <div onclick = "function () {thử {handler1 (); handler2 (); handler3 ();} bắt {}}"> </ div>
Kira

15

Bạn có thể kết hợp chúng, sử dụng jQuery để liên kết hàm với nhấp chuột

<div id="myDiv">Some Content</div>

$('#myDiv').click(divFunction);

function divFunction(){
 //some code
}

14

$('#myDiv').clicklà tốt hơn, bởi vì nó tách mã JavaScript khỏi HTML . Người ta phải cố gắng giữ cho hành vi và cấu trúc trang khác nhau . Điều này giúp rất nhiều.


2
Câu trả lời này có ý nghĩa khi những người thiết kế và viết công cụ js khác nhau trong hầu hết các trường hợp. Và cảm thấy kỳ lạ khi nâng cấp nó sau gần 4 năm kể từ khi nó được đăng !!
Học tập vào

14

Đi cho điều này vì nó sẽ cung cấp cho bạn cả tiêu chuẩn và hiệu suất.

 $('#myDiv').click(function(){
      //Some code
 });

Vì phương thức thứ hai là mã JavaScript đơn giản và nhanh hơn jQuery. Nhưng ở đây hiệu suất sẽ xấp xỉ như nhau.


11

IMHO, onclick là phương thức ưa thích hơn .click chỉ khi các điều kiện sau được đáp ứng:

  • có nhiều yếu tố trên trang
  • chỉ có một sự kiện được đăng ký cho sự kiện nhấp chuột
  • Bạn lo lắng về hiệu suất di động / tuổi thọ pin

Tôi đã hình thành ý kiến ​​này vì thực tế là các công cụ JavaScript trên thiết bị di động chậm hơn 4 đến 7 lần so với các máy tính để bàn của chúng được tạo ra trong cùng một thế hệ. Tôi ghét nó khi tôi truy cập một trang web trên thiết bị di động của mình và nhận được cuộn dữ dội vì jQuery đang ràng buộc tất cả các sự kiện với chi phí trải nghiệm người dùng và thời lượng pin của tôi. Một yếu tố hỗ trợ gần đây, mặc dù điều này chỉ là mối quan tâm với các cơ quan chính phủ;), chúng tôi đã bật lên IE7 với một hộp thông báo cho biết quá trình JavaScript đang kéo dài ... chờ hoặc hủy quá trình. Điều này xảy ra mỗi khi có rất nhiều yếu tố liên kết thông qua jQuery.


10

Sự khác biệt trong công việc. Nếu bạn sử dụng click (), bạn có thể thêm một số hàm, nhưng nếu bạn sử dụng một thuộc tính, chỉ một hàm sẽ được thực thi - hàm cuối cùng.

BẢN GIỚI THIỆU

HTML

<span id="JQueryClick">Click #JQuery</span> </br>
<span id="JQueryAttrClick">Click #Attr</span> </br>

JavaScript

$('#JQueryClick').click(function(){alert('1')})
$('#JQueryClick').click(function(){alert('2')})

$('#JQueryAttrClick').attr('onClick'," alert('1')" ) //This doesn't work
$('#JQueryAttrClick').attr('onClick'," alert('2')" )

Nếu chúng ta đang nói về hiệu suất, trong mọi trường hợp sử dụng trực tiếp luôn nhanh hơn, nhưng sử dụng một thuộc tính, bạn sẽ chỉ có thể gán một chức năng.


Chúng tôi có thể thực thi nhiều hàm bằng cách sử dụng thuộc tính như $ ('# JQueryAttrClick'). Attr ('onClick', "alert ('2'); alert ('3'); alert ('4')")
Kira

8

Sự quan tâm của vấn đề là chìa khóa ở đây, và vì vậy ràng buộc sự kiện là phương pháp thường được chấp nhận. Đây là cơ bản những gì rất nhiều câu trả lời hiện có đã nói.

Tuy nhiên đừng vứt bỏ ý tưởng đánh dấu khai báo quá nhanh. Nó có vị trí của nó, và với các khung như Angularjs, là trung tâm.

Cần phải có một sự hiểu biết rằng toàn bộ <div id="myDiv" onClick="divFunction()">Some Content</div>đã bị xấu hổ rất nhiều vì nó bị lạm dụng bởi một số nhà phát triển. Vì vậy, nó đạt đến điểm của tỷ lệ bất khả xâm phạm, rất giống tables. Một số nhà phát triển thực sự tránh tablescho dữ liệu dạng bảng. Đó là ví dụ hoàn hảo về những người hành động mà không hiểu gì.

Mặc dù tôi thích ý tưởng giữ hành vi của mình tách biệt khỏi quan điểm của tôi. Tôi thấy không có vấn đề gì với việc đánh dấu tuyên bố những gì nó làm (không phải nó hoạt động như thế nào , đó là hành vi). Nó có thể ở dạng thuộc tính onClick thực tế hoặc thuộc tính tùy chỉnh, giống như các thành phần javascript của bootstraps.

Bằng cách này, bằng cách chỉ nhìn vào đánh dấu, bạn có thể thấy những gì đang làm, thay vì cố gắng đảo ngược các ràng buộc sự kiện javascript.

Vì vậy, như là một thay thế thứ ba cho các bên trên, sử dụng các thuộc tính dữ liệu để thông báo rõ ràng hành vi trong đánh dấu. Hành vi được giữ ngoài tầm nhìn, nhưng trong nháy mắt bạn có thể thấy những gì đang xảy ra.

Ví dụ về Bootstrap:

<button type="button" class="btn btn-lg btn-danger" data-toggle="popover" title="Popover title" data-content="And here's some amazing content. It's very engaging. Right?">Click to toggle popover</button>

Nguồn: http://getbootstrap.com/javascript/#popovers

Lưu ý Nhược điểm chính với ví dụ thứ hai là sự ô nhiễm của không gian tên toàn cầu. Điều này có thể được phá vỡ bằng cách sử dụng thay thế thứ ba ở trên hoặc các khung như Angular và các thuộc tính ng-click của chúng với phạm vi tự động.


4

Không ai tốt hơn ở chỗ chúng có thể được sử dụng cho các mục đích khác nhau. onClick(thực sự nên onclick) thực hiện tốt hơn một chút, nhưng tôi rất nghi ngờ bạn sẽ nhận thấy một sự khác biệt ở đó.

Điều đáng chú ý là họ làm những việc khác nhau: .clickcó thể bị ràng buộc với bất kỳ bộ sưu tập jQuery nào trong khi onclickphải sử dụng nội tuyến trên các yếu tố bạn muốn nó bị ràng buộc. Bạn cũng có thể liên kết chỉ một sự kiện để sử dụng onclick, trong khi .clickcho phép bạn tiếp tục liên kết các sự kiện.

Theo ý kiến ​​của tôi, tôi sẽ nhất quán về nó và chỉ sử dụng .clickở mọi nơi và giữ tất cả các mã JavaScript của tôi lại với nhau và tách khỏi HTML.

Đừng sử dụng onclick. Không có bất kỳ lý do để sử dụng nó trừ khi bạn biết những gì bạn đang làm, và bạn có thể không.


2
Ngay cả khi "tốt hơn" không được xác định rõ ràng, gần như không bao giờ nên đưa người xử lý sự kiện vào đánh dấu của bạn trực tiếp
Jay

@Jayraj tôi đã bao giờ nói trong câu trả lời của mình đó là một ý tưởng tốt?
Thuốc nổ

3
Bằng cách nói .clickkhông tốt hơn onclick("Không ai tốt hơn "), nó được ngụ ý onclickgần như, hoặc cũng là một cách tốt để viết mã, trong khi thực tế .clicklà cách tốt hơn một dặm. Xin lỗi, nhưng IMHO bạn nên viết lại câu trả lời của mình
Jay

2
@ExplumpingPills Tôi sẽ loại bỏ phần câu trả lời không nói là tốt hơn. Đoạn văn ở cuối nghe có vẻ mâu thuẫn.
Juan Mendes

4
<whatever onclick="doStuff();" onmouseover="in()" onmouseout="out()" />

các sự kiện onclick, onmouseover, onmouseout, v.v ... thực sự không tốt cho hiệu suất ( chủ yếu trong Internet Explorer , hãy tìm hiểu). Nếu bạn viết mã bằng Visual Studio , khi bạn chạy một trang với những trang này, mỗi một trang sẽ tạo một khối SCRIPT riêng chiếm bộ nhớ và do đó làm chậm hiệu suất.

Chưa kể bạn nên có một mối quan tâm riêng biệt: JavaScript và bố cục nên được tách ra!

Luôn luôn tốt hơn để tạo các Trình xử lý đồng đều cho bất kỳ sự kiện nào trong số này, một sự kiện có thể thu được hàng trăm / nghìn mục, thay vì tạo hàng ngàn khối tập lệnh riêng biệt cho mỗi sự kiện!

(Ngoài ra, mọi thứ người khác đang nói.)


3

Chà, một trong những ý tưởng chính đằng sau jQuery là tách JavaScript khỏi mã HTML khó chịu . Phương pháp đầu tiên là con đường để đi.


3

Hầu hết thời gian, các phương thức JavaScript gốc là một lựa chọn tốt hơn so với jQuery khi hiệu suất là tiêu chí duy nhất, nhưng jQuery sử dụng JavaScript và làm cho việc phát triển trở nên dễ dàng. Bạn có thể sử dụng jQuery vì nó không làm giảm hiệu suất quá nhiều. Trong trường hợp cụ thể của bạn, sự khác biệt của hiệu suất là không thể biết được.


2

Phương pháp sử dụng đầu tiên onclickkhông phải là jQuery mà chỉ đơn giản là Javascript, vì vậy bạn không có được chi phí hoạt động của jQuery. Cách jQuery có thể mở rộng thông qua các bộ chọn nếu bạn cần thêm nó vào các phần tử khác mà không cần thêm trình xử lý sự kiện cho mỗi phần tử, nhưng như bạn có bây giờ, nó chỉ là một câu hỏi nếu bạn có cần sử dụng jQuery hay không.

Cá nhân vì bạn đang sử dụng jQuery, tôi sẽ sử dụng nó vì nó phù hợp và không tách rời đánh dấu khỏi tập lệnh.


1
Ví dụ jQuery thực tế giống document.querySelector('#something').addEventListener(...hoặc tương tự trong Javascript đơn giản, vì vậy đó không phải là vấn đề. Tương tự, bạn có thể bắt các sự kiện sủi bọt từ các nút con trong Javascript, không chỉ với các phím tắt jQuery. Trọng tâm của vấn đề là những sự kiện này phải nằm trong bộ điều khiển (tệp định nghĩa hành vi javascript) chứ không phải dạng xem (nằm rải rác ở đây và trong html, yêu cầu các hàm biến toàn cục hoặc tệ hơn là mã nội tuyến.)
NoBugs

2

Phương pháp đầu tiên là thích. Nó sử dụng mô hình đăng ký sự kiện nâng cao [s] , có nghĩa là bạn có thể đính kèm nhiều trình xử lý vào cùng một phần tử. Bạn có thể dễ dàng truy cập đối tượng sự kiện và trình xử lý có thể sống trong bất kỳ phạm vi chức năng nào. Ngoài ra, nó là động, tức là nó có thể được gọi bất cứ lúc nào và đặc biệt phù hợp với các yếu tố được tạo động. Cho dù bạn sử dụng jQuery, một thư viện khác hoặc các phương thức gốc trực tiếp không thực sự quan trọng.

Phương thức thứ hai, sử dụng các thuộc tính nội tuyến, cần rất nhiều hàm toàn cục (dẫn đến ô nhiễm không gian tên) và trộn nội dung / cấu trúc (HTML) với hành vi (JavaScript). Đừng dùng cái đó.

Câu hỏi của bạn về hiệu suất hoặc tiêu chuẩn không thể dễ dàng được trả lời. Hai phương pháp hoàn toàn khác nhau, và làm những điều khác nhau. Cái thứ nhất là hùng mạnh hơn, trong khi cái thứ hai bị coi thường (được coi là phong cách xấu).


1

Chức năng Onclick Jquery

$('#selector').click(function(){ //Your Functionality });

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.