我有一个巨大的jQuery应用程序,我正在使用下面的两个方法来处理点击事件。

第一个方法

HTML

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

jQuery

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

第二种方法

HTML

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

JavaScript函数调用

function divFunction(){
    //Some code
}

在我的应用程序中,我使用第一种或第二种方法。哪个更好?性能更好?和标准?


当前回答

性能

这里已经有很多很好的答案,然而,作者有时会提到性能,但实际上还没有人调查它-所以我将在这里集中讨论这方面。今天,我在Chrome 83.0, Safari 13.1和Firefox 77.0上进行测试,以解决上述问题和其他一些替代解决方案(其中一些在其他答案中提到)。

结果

我比较这里的A-H解因为它们作用于元素id。我还展示了使用类(I,J,K)作为参考的解的结果。

基于html内联处理程序绑定(B)的解决方案是快速和最快的Chrome和最快的少量元素 基于getElementById (C,D)的解决方案是快速的,对于大量的元素,在Safari和Firefox上最快 基于I,J的参考解决方案对于大数量的元素是最快的,所以在这种情况下值得考虑使用类代替id方法 基于jQuery的解决方案。点击(A)最慢

细节

实际上,针对这一问题设计性能测试并不容易。我注意到,对于所有测试的解决方案,10K div-s触发事件的性能都很快,手动我无法检测到它们之间的任何差异(你可以运行下面的代码片段自己检查)。因此,针对两种情况,我着重测量生成html和绑定事件处理程序的执行时间

10个div -你可以在这里运行测试 1000 div -你可以在这里运行测试

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

下面是Chrome的测试示例

其他回答

使用onclick的第一种方法不是jQuery,而是简单的Javascript,所以您没有jQuery的开销。jQuery的方式可以通过选择器进行扩展,如果你需要将它添加到其他元素,而不需要为每个元素添加事件处理程序,但现在你有了它,是否需要使用jQuery只是一个问题。

就我个人而言,因为你正在使用jQuery,我会坚持使用它,因为它是一致的,并从脚本中解耦标记。

使用$('#myDiv').click(function(){更好,因为它遵循标准的事件注册模型。(jQuery内部使用addEventListener和attachEvent)。

基本上,以现代方式注册事件是处理事件的一种不引人注目的方式。另外,要为目标注册多个事件监听器,可以为同一个目标调用addEventListener()。

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.

更多关于现代活动注册-> http://www.quirksmode.org/js/events_advanced.html

其他方法,如设置HTML属性,示例:

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

或DOM元素属性,示例:

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

都是旧的,而且很容易被重写。

应该避免使用HTML属性,因为它会使标记更大,可读性更差。内容/结构和行为的关注点没有很好地分开,使得错误更难被发现。

DOM元素属性方法的问题在于,每个事件只能将一个事件处理程序绑定到一个元素。

更多关于传统事件处理-> http://www.quirksmode.org/js/events_tradmod.html

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

为了获得更好的性能,请使用本机JavaScript。为了更快地开发,请使用jQuery。查看jQuery和原生元素性能的比较。

我在Windows Server 2008 R2 / 7 64位的Firefox 16.0 32位上进行了测试

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

对于点击事件,检查本机浏览器事件vs jquery触发器或jquery vs本机点击事件绑定。

在Windows Server 2008 R2 / 7 64位的Chrome 22.0.1229.79 32位上测试

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

你可以结合它们,使用jQuery将函数绑定到点击

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

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

function divFunction(){
 //some code
}

恕我直言,onclick是优于.click的首选方法,仅当满足以下条件时:

页面上有很多元素 要为单击事件注册的事件只有一个 你担心手机性能/电池寿命

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.