590
votes

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
You can learn about the various ways to attach event handlers and their advantages/disadvantages here: quirksmode.org/js/introevents.html. jQuery is just a nice wrapper for advanced event registration.Felix Kling
Remember to put the click function inside the $(document).ready(function().joan16v

17 Answers

588
votes

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

67
votes

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

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.

19
votes

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
}
17
votes

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.

15
votes

$('#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.

11
votes

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.

11
votes

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.

10
votes

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.

5
votes
<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.)

4
votes

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.

3
votes

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.

3
votes

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.

2
votes

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.

2
votes

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

2
votes

Onclick Function Jquery

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

2
votes

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://stackguides.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