I have a huge jQuery application, and I\'m using the below two methods for click events.
First method
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.
Onclick Function Jquery
$('#selector').click(function(){
//Your Functionality
});
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
<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.)
IMHO, onclick is the preferred method over .click only when the following conditions are met:
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.
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).
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.
getElementById
(C,D) are fast, and for big number of elements fastest on Safari and Firefoxclass
instead id
approach in this caseActually 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
div
s - you can run test HEREdiv
s - 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