我目前正在构建一个允许搜索元素的网站,并将结果添加到一个大表中(想想数百个结果)。结果表中的每个元素都可以通过各种方式进行操作(自定义javascript 0-5星级,切换折叠面板以获取其他选项等)。
如果我在Android平板电脑上使用该网站,那么javascript部分的性能非常低迷,所以我想知道如何提高性能。
我考虑的一个选项是不绑定结果行上的任何事件侦听器,除了单个鼠标输入事件,然后仅当鼠标位于给定元素上时绑定实际的事件侦听器。
非常感谢任何提高性能的其他想法。
我的大多数javascript代码都是基于jquery的,所以如果你有任何jquery特定的优化,我也会很感激。
答案 0 :(得分:9)
您可以查看javaScript 事件委派。关于SO(示例here)和许多好文章(here或here)有很多答案。
基本上你的想法实际上是一个很好的解决方案。所以,不要绑定 - 比方说 - 用他们自己的事件处理程序一百行,你只绑定他们的共同父,当它的任何一个孩子将收到一个鼠标输入时将触发一个事件
粗略地说而不是:
$('tr').on("click", function() {});
你会这样做:
$('table').on('click', 'tr', function() {});
这显然是一个非常简单的例子,但它应该足以构建一个好的模式。
作为旁注,这是一个非常有趣的事情(好吧,至少对我来说......)来检查被解雇的事件,例如:
$('table').on('click', 'tr', function(evt) {
console.log(evt);
});
查看活动所包含的信息量,以及通过简单的点击或鼠标输入即可获得多少有用的信息。
<强> VanillaJs 强>
当然,没有任何库可以实现相同的结果。
使用Vanilla JS的简单实现可以从David Walsh在答案开头链接的文章中获取,大致如下:
// Get the element, add a click listener...
document.getElementById("#myTable").addEventListener("click", function(e) {
// e.target is the clicked element.
// Check if it was a <tr>...
if(e.target && e.target.nodeName == "TR") {
// Element has been found, do something with it
}
});
如果您尝试使用此代码,但实际的target.element
可能是<td>
,而不是我们想要的<tr>
。
这意味着我们必须更加聪明并向上走DOM,看看点击的元素(<td>
)是否包含在我们真正想要的那个(<tr>
)中。
让你开始的粗略实现看起来像这样:
function walk(startEl, stopEl, targetNodeName) {
if (!startEl || startEl === stopEl || startEl.nodeName === 'BODY') {
return false;
}
if (startEl.nodeName === targetNodeName) {
// Found it, return the element
return startEl;
}
// Keep on looking...
return walk(startEl.parentNode, stopEl, targetNodeName);
}
const container = document.getElementById('myTable');
container.addEventListener('click', (e) => {
const clickedElm = walk(e.target, container, 'TR');
console.log(clickedElm);
if (clickedElm) {
clickedElm.classList.add('clicked');
}
})
请参阅此fiddle或以下代码段:
function walk(startEl, stopEl, targetNodeName) {
if (!startEl || startEl === stopEl || startEl.nodeName === 'BODY') {
return false;
}
if (startEl.nodeName === targetNodeName) {
return startEl;
}
return walk(startEl.parentNode, stopEl, targetNodeName);
}
const elem = document.getElementById('myTable');
elem.addEventListener('click', (e) => {
const clickedElm = walk(e.target, elem, 'TR');
console.log(clickedElm);
if (clickedElm) {
clickedElm.classList.add('clicked');
}
})
&#13;
table {
width: 100%;
}
tr {
background: #ddd;
}
.clicked {
background: teal;
}
&#13;
<table id="myTable">
<tr>
<td>one</td>
</tr>
<tr>
<td>two</td>
</tr>
<tr>
<td>three</td>
</tr>
<tr>
<td>four</td>
</tr>
<tr>
<td>five</td>
</tr>
<tr>
<td>six</td>
</tr>
</table>
&#13;