jQuery.click() vs onClick

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

第一个方法

超文本标记语言

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

jQuery

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

第二种方法

超文本标记语言

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

JavaScript函数调用

function divFunction(){
//Some code
}

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

1604054 次浏览

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

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

var myEl = document.getElementById('myelement');


myEl.addEventListener('click', function() {
alert('Hello world');
}, false);


myEl.addEventListener('click', function() {
alert('Hello world again!!!');
}, false);

# EYZ0

为什么使用addEventListener?< / >(来自MDN)

addEventListener是指定的注册事件监听器的方式 在W3C DOM中。其好处如下:

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

更多关于现代事件注册- ># EYZ0

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

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

DOM元素属性,示例:

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

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

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

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

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

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

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

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


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


function divFunction(){
//some code
}

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

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

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

大多数情况下,当性能是唯一的标准时,原生JavaScript方法是比jQuery更好的选择,但是jQuery利用了JavaScript并使开发变得容易。可以使用jQuery,因为它不会严重降低性能。在你的具体情况下,性能的差异是可以忽略的。

两者都不是更好的,因为它们可以用于不同的目的。onClick(实际上应该是onclick)执行得稍微好一点,但我非常怀疑您是否会注意到其中的差异。

值得注意的是,它们做不同的事情:.click可以绑定到任何jQuery集合,而onclick必须内联使用在你想要它绑定的元素上。您也可以使用onclick只绑定一个事件,而.click允许您继续绑定事件。

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

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

$('#myDiv').click更好,因为它将JavaScript代码从超文本标记语言中分离出来。你必须尽量保留行为和结构不同页。这很有帮助。

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

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

好吧,jQuery背后的主要思想之一是将JavaScript与令人讨厌的超文本标记语言代码分开。第一种方法是要走的路。

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

我在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 Native Click事件绑定 .

在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。而是:在HTML中内联绑定事件更好,还是通过事件监听器绑定事件更好?

不支持内联绑定。此外,通过这种方式,您只能将一个函数绑定到某个事件。

因此,我建议使用事件侦听器。通过这种方式,您将能够将许多函数绑定到单个事件,并在需要时稍后取消它们的绑定。考虑这段纯JavaScript代码:

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

这在大多数现代浏览器中都有效。

然而,如果你已经在你的项目中包含了jQuery -只需使用jQuery: .on.click函数。

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

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

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

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

(还有,所有人都在说的话。)

不同的作品。如果使用click(),则可以添加几个函数,但如果使用属性,则只执行一个函数—最后一个函数。

DEMO

< em > < / HTML em >

<span id="JQueryClick">Click #JQuery</span> </br>
<span id="JQueryAttrClick">Click #Attr</span> </br>

JavaScript < em > < / em >

$('#JQueryClick').click(function(){alert('1')})
$('#JQueryClick').click(function(){alert('2')})


$('#JQueryAttrClick').attr('onClick'," alert('1')" ) //This doesn't work
$('#JQueryAttrClick').attr('onClick'," alert('2')" )

如果我们谈论的是性能,在任何情况下直接使用总是更快,但使用属性,您将只能分配一个函数。

这样做,因为它将为您提供标准和性能。

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

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

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

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

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

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

然而不要过快地抛弃声明性标记的想法。它有它的位置,和像Angularjs这样的框架一起,它是核心。

大家应该认识到,整个<div id="myDiv" onClick="divFunction()">Some Content</div>之所以受到如此严重的羞辱,是因为一些开发人员滥用了它。所以它达到了亵渎的程度,就像tables一样。对于表格数据,一些开发人员实际上避免使用tables。这是人们不理解行为的完美例子。

尽管我喜欢把我的行为和我的观点分开。我认为标记声明什么没有任何问题(不是如何它做它,这是行为)。它可能是一个实际的onClick属性的形式,也可能是一个自定义属性的形式,很像bootstrap 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>

来源:# EYZ0

第二个示例的主要缺点是对全局名称空间的污染。这可以通过使用上面的第三种选择来避免,或者使用像Angular这样的框架及其带有自动作用域的ng-click属性。

Onclick函数Jquery

< p > <代码> $(“#选择器”).click(函数(){ / /你的功能 }); < /代码> < / p >

性能

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

结果

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

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

enter image description here

细节

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

// 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的测试示例

enter image description here

说你有一个按钮嵌套在Javascript/Jquery生成的html元素(.html()或.innerHTML类型的元素),然后你需要首先选择最外层的元素(父元素),并这样做

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

我所说的最外层元素是指嵌入.html()的元素

outermostElement.html("<div><button>click<button><div>")