性能
这里已经有很多很好的答案,然而,作者有时会提到性能,但实际上还没有人调查它-所以我将在这里集中讨论这方面。今天,我在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的测试示例