By Techie


2012-09-27 18:02:02 8 Comments

I have a huge jQuery application, and I'm using the below two methods for click events.

First method

HTML

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

jQuery

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

Second method

HTML

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

JavaScript function call

function divFunction(){
    //Some code
}

I use either the first or second method in my application. Which one is better? Better for performance? And standard?

17 comments

@Kamil Kiełczewski 2020-06-26 08:31:58

Performance

There are already many good answers here however, authors sometimes mention about performance but actually nobody investigate it yet - so I will focus on this aspect here. Today I perform test on Chrome 83.0, Safari 13.1 and Firefox 77.0 for solutions mention in question and additionally few alternative solutions (some of them was mention in other answers).

Results

I compare here solutions A-H because they operate on elements id. I also show results for solutions which use class (I,J,K) as reference.

  • solution based on html-inline handler binding (B) is fast and fastest for Chrome and fastest for small number of elements
  • solutions based on getElementById (C,D) are fast, and for big number of elements fastest on Safari and Firefox
  • referenced solutions I,J based are fastest for big num of elements so It is worth to consider use class instead id approach in this case
  • solution based on jQuery.click (A) is slowest

enter image description here

Details

Actually It was not easy to design performance test for this question. I notice that for all tested solutions, performance of triggering events for 10K div-s was fast and manually I was not able to detect any differences between them (you can run below snippet to check it yourself). So I focus on measure execution time of generate html and bind event handlers for two cases

  • 10 divs - you can run test HERE
  • 1000 divs - you can run test HERE

// https://stackoverflow.com/questions/12627443/jquery-click-vs-onclick
let a= [...Array(10000)];

function clean() { test.innerHTML = ''; console.clear() }

function divFunction(el) {
  console.log(`clicked on: ${el.id}`);
}

function initA() {
  test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
  a.map((x,i)=> $(`#myDiv${i}`).click(e=> divFunction(e.target)));
}

function initB() {
  test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box" onclick="divFunction(this)">${i}</div>`).join``;
}

function initC() {
  test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
  a.map((x,i)=> document.getElementById(`myDiv${i}`).onclick = e=> divFunction(e.target) );
}

function initD() {
  test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
  a.map((x,i)=> document.getElementById(`myDiv${i}`).addEventListener('click', e=> divFunction(e.target) ));
}

function initE() {
  test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
  a.map((x,i)=> document.querySelector(`#myDiv${i}`).onclick = e=> divFunction(e.target) );
}

function initF() {
  test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
  a.map((x,i)=> document.querySelector(`#myDiv${i}`).addEventListener('click', e=> divFunction(e.target) ));
}

function initG() {
  test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
  a.map((x,i)=> window[`myDiv${i}`].onclick = e=> divFunction(e.target) );
}

function initH() {
  test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
  a.map((x,i)=> window[`myDiv${i}`].addEventListener('click',e=> divFunction(e.target)));
}

function initI() {
  test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
  [...document.querySelectorAll(`.box`)].map(el => el.onclick = e=> divFunction(e.target));
}

function initJ() {
  test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
  [...document.querySelectorAll(`.box`)].map(el => el.addEventListener('click', e=> divFunction(e.target)));
}

function initK() {  
  test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
  $(`.box`).click(e=> divFunction(e.target));
}



function measure(f) {  
  console.time("measure "+f.name);
  f();
  console.timeEnd("measure "+f.name)
}
#test {
  display: flex;
  flex-wrap: wrap;
}

.box {
  margin: 1px;
  height: 10px;
  background: red;
  font-size: 10px;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>This snippet only presents used solutions. Click to solution button and then click on any red box to trigger its handler</div>
<button onclick="measure(initA)">A</button>
<button onclick="measure(initB)">B</button>
<button onclick="measure(initC)">C</button>
<button onclick="measure(initD)">D</button>
<button onclick="measure(initE)">E</button>
<button onclick="measure(initF)">F</button>
<button onclick="measure(initG)">G</button>
<button onclick="measure(initH)">H</button>
<button onclick="measure(initI)">I</button>
<button onclick="measure(initJ)">J</button>
<button onclick="measure(initK)">K</button>
<button onclick="clean()">Clean</button>

<div id="test"></div>

Here is example test for Chrome

enter image description here

@Love Kumar 2019-06-11 08:18:24

Onclick Function Jquery

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

@Michał Miszczyszyn 2012-09-27 18:12:02

From what I understand, your question is not really about whether to use jQuery or not. It's rather: Is it better to bind events inline in HTML or through event listeners?

Inline binding is deprecated. Moreover this way you can only bind one function to a certain event.

Therefore I recommend using event listeners. This way, you'll be able to bind many functions to a single event and to unbind them later if needed. Consider this pure JavaScript code:

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

This works in most modern browsers.

However, if you already include jQuery in your project — just use jQuery: .on or .click function.

@Kira 2017-03-14 09:37:18

It is possible to register multiple functions using inline HTML like <div onclick="handler1();handler2();handler3();"></div>

@Michał Miszczyszyn 2017-03-14 14:39:31

This way you're still registering only one "expression". For example, if handler1 throws an error, handler2 and handler3 won't ever get called. Moreover, you're unable to dynamically add and remove certain fuctions from the listener. And last but not least, handler1, handler2 and handler3 have to be declared in the global scope which is a smell.

@Michał Miszczyszyn 2017-03-16 16:20:24

Using try..catch inside the functions won't work when handler2 in undefined. FYI inline JavaScript obviously doesn't work when JS is disabled in user's browser, please do not misinform others.

@Kira 2017-03-17 04:05:33

I mentioned I was not sure about disabled JavaScript. I am not misinforming or deceiving others

@Kira 2017-03-17 04:10:48

In that case you can try the following <div onclick="function() { try { handler1();handler2();handler3(); } catch { } }"></div>

@Michał Miszczyszyn 2017-03-19 17:56:39

Oh, wow, it's both more readable and certainly more convenient than addEventListener. Keep up with the good code!

@Selvakumar Arumugam 2012-09-27 18:04:14

Using $('#myDiv').click(function(){ is better as it follows standard event registration model. (jQuery internally uses addEventListener and attachEvent).

Basically registering an event in modern way is the unobtrusive way of handling events. Also to register more than one event listener for the target you can call addEventListener() for the same target.

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/

Why use addEventListener? (From MDN)

addEventListener is the way to register an event listener as specified in W3C DOM. Its benefits are as follows:

  • It allows adding more than a single handler for an event. This is particularly useful for DHTML libraries or Mozilla extensions that need to work well even if other libraries/extensions are used.
  • It gives you finer-grained control of the phase when the listener gets activated (capturing vs. bubbling)
  • It works on any DOM element, not just HTML elements.

More about Modern event registration -> http://www.quirksmode.org/js/events_advanced.html

Other methods such as setting the HTML attributes, example:

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

Or DOM element properties, example:

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

are old and they can be over written easily.

HTML attribute should be avoided as It makes the markup bigger and less readable. Concerns of content/structure and behavior are not well-separated, making a bug harder to find.

The problem with the DOM element properties method is that only one event handler can be bound to an element per event.

More about Traditional event handling -> http://www.quirksmode.org/js/events_tradmod.html

MDN Reference: https://developer.mozilla.org/en-US/docs/DOM/event

@zuallauz 2012-09-27 21:28:56

Lets say you run the $('#myDiv').click(function(){ code first, then you generate 20 rows of HTML dynamically from JavaScript and each row has a button on it that when clicked the JavaScript is required to execute that same function. If you do that first then it won't work as the event handler has been added before the HTML has been generated. It would seem easier to just throw in the onclick="functionName()" into the dynamically generated HTML then the button works straight away. Or do you know of a more elegant solution for this situation?

@Zefiryn 2012-09-27 22:54:08

@zuallauz for that case jQuery offers .delegate() function. It will attach event to any element that will appear in the future on the site.

@zuallauz 2012-09-27 23:38:30

@Zefiryn Thanks that function sounds great, I'll be using that in future!

@Simon Robb 2012-09-28 00:12:56

@zuallauz the jQuery .live() function might be an simpler solution for what you are after http://api.jquery.com/live/. A good article on the differences between .bind(), .live() and .delegate() here

@Selvakumar Arumugam 2012-09-28 00:27:29

@SimonRobb .live is deprecated. Use .delegate for older versions or use .on for newer jQuery versions.

@supertonsky 2012-12-20 06:49:35

@Vega, Good points. What about readability? Now you have to search all referenced JS files on the page to see all click handlers of an element by element's ID instead of searching for the function name. What's your take on this?

@Jon 2013-06-26 13:03:47

I agree with @supertonsky. I STRONGLY disagree that $('#myDiv').click(function(){ is better. In a large javascript application binding with an event becomes massively difficult to find all the references binding to that target. Is it the binding on a class, an id, a child references to a html tag? And what happens if css changes and class names you bound to need to be changed? In my experience working with others code it becomes very ugly very fast.

@Selvakumar Arumugam 2013-06-26 14:31:40

@Jon Your disagreement is based on bad coding practices. If the code is ugly, you should consider refactoring it.. but not disagree on a better approach just because it is hard to find reference in a ugly code. Also, It is easy to find the reference if you follow a simple rule to bind the handler only by an ID or class. Any other way such as binding using traversal methods is bad coding and you cannot blame the standard if it is poor code.

@Selvakumar Arumugam 2013-06-26 17:24:10

@supertonsky I believe searching by ID or class or by function name in js files is same. However it is very hard when you bind a handler using a traversal method like $('#myTable').find('tr').click( or $('.someclass').parent().click( - but those are bad coding styles.

@NoBugs 2014-08-02 00:17:18

@Jon Having multiple elements with the same ID is bad coding in general, and may have erratic behavior. Instead, for multiple items with a listener it is proper to do jQuery('#container').on('click','.listitem', function(){...}) or in plain javascript, set document.getElementById('container').addEventListener(... and check event.target.getAttribute('class') in the listener.

@WynandB 2014-08-28 02:39:13

@supertonsky At least we now have the ability to use the HTML panel's Events tab in Firebug. I know it's not exactly what you're after but nonetheless, it remains a great aid which allows you to inspect the actual event listeners registered for a selected DOM node at any given time, as opposed to scanning the code base and looking at ones that might be registered at some point.

@Intacto 2017-10-24 14:05:37

I have a trouble use this code without run it inside of ready jquery function: $(document).ready(function() { ... });

@Lucian Minea 2018-04-20 08:59:33

Although the answer is very good, nobody seems to question the purpose of onClick events, no matter the way of calling it. The purpose is to trigger an action without refreshing the page, but in 99% of the cases we need to pass one or more parameters. In that case, it really doesn't matter if you use data-param="value" or onClick="function(param)", either way they are visible and can be overwritten. I'm using onClick, but I always check and sanitise everything before processing the data, so it doesn't matter to me fi the parameters are visible.

@Alex 2019-05-19 20:05:29

"HTML attribute should be avoided as It makes the markup bigger" oh yeah, but now I have to give id to all my elelements. Also, LOVE answers that say "should be avoided because its wrong"

@izzulmakin 2019-12-24 02:53:09

"HTML attribute should be avoided as It makes the markup bigger" having this in mind will lead to spaghetti code, HTML attribute event is 100% valid. I don't mind if ID used in getting element to bind the event. but i've seen so many "senior" developer using long query with class only. The result? other developer will have a hard time searching where the functionality of the event. I believe the best practice is using anything where other developer can find the function easily, people on vue.js has written about this vuejs.org/v2/guide/events.html#Why-Listeners-in-HTML

@kishor10d 2020-02-25 08:51:45

This is general comment. Some comments are saying live is deprecated, use delegate or on instead etc. But some of us, are still using live and delegate. They don't want to upgrade. This is sad.

@Chris 2014-10-18 12:16:53

Seperation of concerns is key here, and so the event binding is the generally accepted method. This is basically what a lot of the existing answers have said.

However don't throw away the idea of declarative markup too quickly. It has it's place, and with frameworks like Angularjs, is the centerpiece.

There needs to be an understanding that the whole <div id="myDiv" onClick="divFunction()">Some Content</div> was shamed so heavily because it was abused by some developers. So it reached the point of sacrilegious proportions, much like tables. Some developers actually avoid tables for tabular data. It's the perfect example of people acting without understanding.

Although I like the idea of keeping my behaviour seperate from my views. I see no issue with the markup declaring what it does (not how it does it, that's behaviour). It might be in the form of an actual onClick attribute, or a custom attribute, much like bootstraps javascript components.

This way, by glancing just at the markup, you can see what is does, instead of trying to reverse lookup javascript event binders.

So, as a third alternative to the above, using data attributes to declarativly announce the behaviour within the markup. Behaviour is kept out of the view, but at a glance you can see what is happening.

Bootstrap example:

<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>

Source: http://getbootstrap.com/javascript/#popovers

Note The main disadvantage with the second example is the pollution of global namespace. This can be circumvented by either using the third alternative above, or frameworks like Angular and their ng-click attributes with automatically scope.

@Anton Baksheiev 2012-09-27 18:32:50

Difference in works. If you use click(), you can add several functions, but if you use an attribute, only one function will be executed - the last one.

DEMO

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')" )

If we are talking about performance, in any case directly using is always faster, but using of an attribute, you will be able to assign only one function.

@Kira 2017-03-14 09:42:51

We can execute more than one functions using attribute like $('#JQueryAttrClick').attr('onClick'," alert('2');alert('3');alert('4')" )

@Adil 2012-09-27 18:05:16

Most of the time, native JavaScript methods are a better choice over jQuery when performance is the only criteria, but jQuery makes use of JavaScript and makes the development easy. You can use jQuery as it does not degrade performance too much. In your specific case, the difference of performance is ignorable.

@Rahul 2012-09-28 06:51:06

Go for this as it will give you both standard and performance.

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

As the second method is simple JavaScript code and is faster than jQuery. But here performance will be approximately the same.

@Mark Pieszak - Trilon.io 2012-09-27 18:18:01

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

onclick, onmouseover, onmouseout, etc. events are actually bad for performance (in Internet Explorer mainly, go figure). If you code using Visual Studio, when you run a page with these, every single one of these will create a separate SCRIPT block taking up memory, and thus slowing down performance.

Not to mention you should have a separation of concerns: JavaScript and layouts should be separated!

It is always better to create evenHandlers for any of these events, one event can capture hundreds/thousands of items, instead of creating thousands of separate script blocks for each one!

(Also, everything everyone else is saying.)

@Kamil Kiełczewski 2020-06-25 15:12:58

What about angular, vue,... - they break concept of separation - and it not induce any problems in applications writen using this frameworks (in fact it speed up proces of creating software) - ?

@Mark Pieszak - Trilon.io 2020-06-26 00:49:59

@KamilKiełczewski Definitely since 2012 a lot has changed! This used to be a major SOC issue back then but now a days we do it everywhere. The only difference I suppose is that we're letting some framework compile our code and take (click) or whatever events and turn them into something different. But it's the same idea in the end right :D Crazy how things come back full circle!

@Kamil Kiełczewski 2020-06-26 06:23:00

I agree with you and I wrote down my thoughts here

@Marian Zburlea 2012-09-27 18:09:54

For better performance, use the native JavaScript. For faster development, use jQuery. Check the comparison in performance at jQuery vs Native Element Performance.

I've done a test in Firefox 16.0 32-bit on Windows Server 2008 R2 / 7 64-bit

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

For click events, check Native Browser events vs jquery trigger or jQuery vs Native Click Event Binding.

Testing in Chrome 22.0.1229.79 32-bit on 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

@Coops 2014-08-06 11:04:34

jQuery should be able to run in many different environments which makes it more robuts and it's easier to write, maintain but if speed is the most important then jQuery is not the answer

@khaled_webdev 2017-11-07 07:22:51

Be careful when using forEach cause is not all browser compatible, i think not for IE for example. Maybe a polyfill will be useful.

@supernova 2012-09-27 18:06:33

Well, one of the main ideas behind jQuery is to separate JavaScript from the nasty HTML code. The first method is the way to go.

@geekman 2012-09-27 18:05:42

$('#myDiv').click is better, because it separates JavaScript code from HTML. One must try to keep the page behaviour and structure different. This helps a lot.

@LearningEveryday 2016-04-14 14:44:33

This answer makes sense as people who design and write js stuff are different in most of the cases. And it feels strange to upvote this after almost 4 years since this was posted!!

@Explosion Pills 2012-09-27 18:05:42

Neither one is better in that they may be used for different purposes. onClick (should actually be onclick) performs very slightly better, but I highly doubt you will notice a difference there.

It is worth noting that they do different things: .click can be bound to any jQuery collection whereas onclick has to be used inline on the elements you want it to be bound to. You can also bind only one event to using onclick, whereas .click lets you continue to bind events.

In my opinion, I would be consistent about it and just use .click everywhere and keep all of my JavaScript code together and separated from the HTML.

Don't use onclick. There isn't any reason to use it unless you know what you're doing, and you probably don't.

@Jay 2012-09-27 19:31:27

Even if "better" isn't explicitly defined, it's almost never a good idea to put event handlers into your markup directly

@Explosion Pills 2012-09-27 20:28:39

@Jayraj when did I ever say in my answer that was a good idea?

@Jay 2012-09-27 20:58:16

By saying .click wasn't better than onclick ("Neither one is better") it was implied that onclick is almost, or just as good a way to write code, when in fact .click is the better practice by a mile. Sorry, but IMHO you should rephrase your answer

@Juan Mendes 2013-03-11 22:00:30

@ExplosionPills I would remove the part of the answer that says neither is better. The paragraph at the end sounds like a contradiction.

@Thomas Vanderhoof 2013-03-19 19:25:15

IMHO, onclick is the preferred method over .click only when the following conditions are met:

  • there are many elements on the page
  • only one event to be registered for the click event
  • You're worried about mobile performance/battery life

I formed this opinion because of the fact that the JavaScript engines on mobile devices are 4 to 7 times slower than their desktop counterparts which were made in the same generation. I hate it when I visit a site on my mobile device and receive jittery scrolling because the jQuery is binding all of the events at the expense of my user experience and battery life. Another recent supporting factor, although this should only be a concern with government agencies ;) , we had IE7 pop-up with a message box stating that JavaScript process is taking to long...wait or cancel process. This happened every time there were a lot of elements to bind to via jQuery.

@Bergi 2012-09-27 18:05:00

The first method is to prefer. It uses the advanced event registration model[s], which means you can attach multiple handlers to the same element. You can easily access the event object, and the handler can live in any function's scope. Also, it is dynamic, i.e it can be invoked at any time and is especially well-suited for dynamically generated elements. Whether you use jQuery, an other library or the native methods directly does not really matter.

The second method, using inline attributes, needs a lot of global functions (which leads to namespace pollution) and mixes the content/structure (HTML) with the behavior (JavaScript). Do not use that.

Your question about performance or standards can't be easily answered. The two methods are just completely different, and do different things. The first one is mightier, while the second one is despised (considered bad style).

@Dustin Laine 2012-09-27 18:05:52

The first method of using onclick is not jQuery but simply Javascript, so you do not get the overhead of jQuery. The jQuery way can expanded via selectors if you needed to add it to other elements without adding the event handler to each element, but as you have it now it is just a question if you need to use jQuery or not.

Personally since you are using jQuery I would stick with it as it is consistent and does decouple the markup from the script.

@NoBugs 2014-08-02 00:54:02

The jQuery example is practically the same thing as document.querySelector('#something').addEventListener(... or similar in plain Javascript, so that isn't the point. Similarly you can catch bubbling events from child nodes in Javascript, not just with jQuery shortcuts. The heart of the matter is these events should be in the controller (javascript behavior definitions file) rather than the view (scattered here and there in the html, requiring global-variable-functions or worse yet, inline code.)

@CaffGeek 2012-09-27 18:04:25

You could combine them, use jQuery to bind the function to the click

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

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

function divFunction(){
 //some code
}

Related Questions

Sponsored Content

11 Answered Questions

21 Answered Questions

25 Answered Questions

[SOLVED] jQuery click events firing multiple times

25 Answered Questions

[SOLVED] How to detect DIV's dimension changed?

13 Answered Questions

[SOLVED] event.preventDefault() vs. return false

7 Answered Questions

[SOLVED] What's the difference between '$(this)' and 'this'?

15 Answered Questions

Sponsored Content