604

我有一个巨大的 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
}

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

4

18 回答 18

600

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

基本上以现代方式注册事件是处理事件的不显眼的方式。此外,要为目标注册多个事件侦听器,您可以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/

为什么要使用 addEventListener?(来自 MDN)

addEventListener 是注册 W3C DOM 中指定的事件侦听器的方法。它的好处如下:

  • 它允许为事件添加多个处理程序。这对于即使使用其他库/扩展也需要正常工作的 DHTML 库或 Mozilla 扩展特别有用。
  • 当侦听器被激活时,它可以让您更精细地控制阶段(捕获与冒泡)
  • 它适用于任何 DOM 元素,而不仅仅是 HTML 元素。

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

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

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

DOM 元素属性,例如:

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

很旧,它们很容易被覆盖。

应避免使用HTML 属性,因为它会使标记更大且可读性更低。对内容/结构和行为的关注没有得到很好的分离,使得 bug 更难被发现。

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

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

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

于 2012-09-27T18:04:14.090 回答
67

为了获得更好的性能,请使用本机 JavaScript。为了加快开发速度,请使用 jQuery。检查jQuery 与 Native Element Performance的性能比较。

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

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

对于点击事件,请检查Native Browser events vs jquery triggerjQuery vs Native Click Event Binding

在 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
于 2012-09-27T18:09:54.393 回答
42

据我了解,您的问题并不是关于是否使用 jQuery。而是:在 HTML 中内联绑定事件还是通过事件侦听器更好?

内联绑定已弃用。此外,您只能将一个函数绑定到某个事件。

因此我推荐使用事件监听器。这样,您将能够将许多函数绑定到单个事件,并在以后需要时取消绑定。考虑这个纯 JavaScript 代码:

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

这适用于大多数现代浏览器。

但是,如果您已经在项目中包含 jQuery — 只需使用 jQuery:.on.clickfunction。

于 2012-09-27T18:12:02.987 回答
21

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

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

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

function divFunction(){
 //some code
}
于 2012-09-27T18:04:25.493 回答
21

去做吧,因为它会给你标准和性能。

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

因为第二种方法是简单的 JavaScript 代码并且比 jQuery 更快。但这里的性能将大致相同。

于 2012-09-28T06:51:06.840 回答
16

$('#myDiv').click更好,因为它将 JavaScript 代码与HTML分开。必须尽量保持页面行为和结构不同。这很有帮助。

于 2012-09-27T18:05:42.793 回答
12

作品的区别。如果你使用click(),你可以添加几个函数,但是如果你使用一个属性,只会执行一个函数——最后一个。

演示

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

如果我们谈论性能,无论如何直接使用总是更快,但是使用属性,您将只能分配一个功能。

于 2012-09-27T18:32:50.583 回答
11

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

  • 页面上有很多元素
  • 点击事件只注册一个事件
  • 您担心移动性能/电池寿命

我之所以形成这种观点,是因为移动设备上的 JavaScript 引擎比同代的桌面引擎慢 4 到 7 倍。当我在移动设备上访问网站并收到抖动的滚动时,我讨厌它,因为 jQuery 以牺牲我的用户体验和电池寿命为代价绑定所有事件。另一个最近的支持因素,虽然这应该只是政府机构的关注;),我们有 IE7 弹出一个消息框,指出 JavaScript 进程需要很长时间......等待或取消进程。每次通过 jQuery 绑定很多元素时都会发生这种情况。

于 2013-03-19T19:25:15.433 回答
10

关注点分离是这里的关键,因此事件绑定是普遍接受的方法。这基本上是许多现有答案所说的。

但是,不要太快放弃声明性标记的想法。它有它的位置,并且像 Angularjs 这样的框架是核心。

需要理解的<div id="myDiv" onClick="divFunction()">Some Content</div>是,由于某些开发人员滥用了整体,因此受到了如此严重的羞辱。所以它达到了亵渎神明的程度,就像tables. 一些开发人员实际上避免tables使用表格数据。这是人们在不理解的情况下行事的完美例子。

虽然我喜欢将我的行为与我的观点分开的想法。我认为标记声明它的作用没有问题(不是它如何做的,这就是行为)。它可能是实际的 onClick 属性或自定义属性的形式,很像引导 javascript 组件。

这样,只需看一眼标记,您就可以看到它做了什么,而不是尝试反向查找 javascript 事件绑定器。

因此,作为上述的第三种替代方法,使用数据属性以声明方式宣布标记内的行为。行为被排除在视图之外,但您一眼就能看到正在发生的事情。

引导示例:

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

来源: http: //getbootstrap.com/javascript/#popovers

注意第二个例子的主要缺点是全局命名空间的污染。这可以通过使用上面的第三种替代方案,或者像 Angular 这样的框架及其具有自动作用域的 ng-click 属性来规避。

于 2014-10-18T12:16:53.410 回答
5
<whatever onclick="doStuff();" onmouseover="in()" onmouseout="out()" />

onclick、onmouseover、onmouseout 等事件实际上对性能不利(主要是在Internet Explorer中,请看图)。如果您使用Visual Studio进行编码,当您使用这些运行页面时,其中的每一个都将创建一个单独的 SCRIPT 块占用内存,从而降低性能。

更不用说你应该分离关注点:JavaScript 和布局应该分离!

为这些事件中的任何一个创建 evenHandlers 总是更好,一个事件可以捕获数百/数千个项目,而不是为每个事件创建数千个单独的脚本块!

(另外,其他人都在说什么。)

于 2012-09-27T18:18:01.320 回答
4

没有一个更好,因为它们可以用于不同的目的。onClick(实际上应该onclick)表现得稍微好一点,但我非常怀疑你会注意到那里的不同。

值得注意的是,它们做了不同的事情:.click可以绑定到任何 jQuery 集合,而onclick必须在您希望绑定到的元素上内联使用。您也可以仅将一个事件绑定到 using onclick,而.click让您继续绑定事件。

在我看来,我会保持一致,只是.click在任何地方使用,并将我的所有JavaScript 代码放在一起并与 HTML 分开。

不要使用onclick. 除非您知道自己在做什么,否则没有任何理由使用它,而且您可能不知道。

于 2012-09-27T18:05:42.643 回答
3

大多数时候,当性能是唯一标准时,本机 JavaScript 方法比 jQuery 更好,但 jQuery 使用 JavaScript 并简化了开发。您可以使用 jQuery,因为它不会过多地降低性能。在您的特定情况下,性能差异是可以忽略的。

于 2012-09-27T18:05:16.633 回答
3

好吧, jQuery背后的主要思想之一是将 JavaScript 与讨厌的HTML代码分开。第一种方法是要走的路。

于 2012-09-27T18:06:33.247 回答
2

第一种方法是偏爱。它使用高级事件注册模型[s],这意味着您可以将多个处理程序附加到同一个元素。您可以轻松访问事件对象,并且处理程序可以存在于任何函数的范围内。此外,它是动态的,即它可以随时调用,特别适合动态生成的元素。无论您使用 jQuery、其他库还是直接使用本机方法都无关紧要。

第二种方法,使用内联属性,需要大量全局函数(这会导致命名空间污染)并将内容/结构(HTML)与行为(JavaScript)混合在一起。不要使用那个。

您关于性能或标准的问题不容易回答。这两种方法只是完全不同,做不同的事情。第一个更强大,而第二个被鄙视(被认为是坏风格)。

于 2012-09-27T18:05:00.877 回答
2

第一种使用onclick方法不是 jQuery,而只是 Javascript,因此您不会得到 jQuery 的开销。如果您需要将 jQuery 方式添加到其他元素而不向每个元素添加事件处理程序,则可以通过选择器扩展 jQuery 方式,但是正如您现在拥有的那样,是否需要使用 jQuery 只是一个问题。

就个人而言,因为您使用的是 jQuery,所以我会坚持使用它,因为它是一致的,并且确实将标记与脚本分离。

于 2012-09-27T18:05:52.213 回答
2

Onclick 函数 Jquery

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

于 2019-06-11T08:18:24.453 回答
2

表现

然而,这里已经有很多好的答案,作者有时会提到性能,但实际上还没有人研究它——所以我将在这里专注于这方面。今天,我在 Chrome 83.0、Safari 13.1 和 Firefox 77.0 上进行了测试,以获取有问题的解决方案以及其他一些替代解决方案(其中一些在其他答案中被提及)。

结果

我在这里比较解决方案 AH 因为它们对元素进行操作id。我还展示了使用class(I,J,K) 作为参考的解决方案的结果。

  • 基于 html-inline 处理程序绑定 (B) 的解决方案对于 Chrome 来说是快速和最快的,对于少量元素来说是最快的
  • 基于getElementById(C,D) 的解决方案速度很快,并且对于 Safari 和 Firefox 上的大量元素最快
  • 基于 I,J 的参考解决方案对于大量元素是最快的,因此在这种情况下值得考虑使用class替代id方法
  • 基于jQuery.click(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 的示例测试

在此处输入图像描述

于 2020-06-26T08:31:58.233 回答
0

假设您有一个嵌套在 Javascript/Jquery 生成的 html 元素(.html() 或 .innerHTML 类型的元素)内的按钮,那么您需要选择最外面的元素(父级)并执行此操作

var parentElement = $('#outermostElement')
 parentElement.click('button', function(){
    console.log('clicked')
}) 

最外层元素是指采用 .html() 的元素,例如

outermostElement.html("<div><button>click<button><div>")
于 2021-12-10T22:07:09.437 回答