首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用多个事件侦听器优化javascript性能

使用多个事件侦听器优化javascript性能
EN

Stack Overflow用户
提问于 2015-03-12 07:40:44
回答 1查看 5.2K关注 0票数 5

我目前正在构建一个允许搜索元素的站点,并将结果添加到一个大表中(想想看数百个结果)。结果表中的每个元素都可以以各种方式操作(定制javascript 0-5星级等级,切换折叠面板以获得其他选项等等)。

如果我在我的android平板电脑上使用这个站点,那么javascript部分的性能就会非常缓慢,所以我想知道如何才能提高性能。

我考虑过的一个选项是,除单个鼠标输入事件外,不绑定结果行上的任何事件侦听器,然后只有当鼠标位于给定元素上时,才绑定实际的事件侦听器。

任何其他提高性能的想法都将不胜感激。

我的大多数javascript代码都是基于jquery的,所以如果您有任何jquery特定的优化,我也会很感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-03-12 07:55:42

您可以查看javaScript 事件委托。关于SO (一个示例这里)和许多好的文章( 这里这里 ),有很多答案。

基本上,你的想法实际上是一个很好的解决方案。因此,与其用自己的事件处理程序绑定100行(比方说),不如将绑定到它们的公共父,当其子节点接收到鼠标输入时,它将触发一个事件。

粗略地说,不是这样的:

代码语言:javascript
复制
$('tr').on("click", function() {});

你会这样做的:

代码语言:javascript
复制
$('table').on('click', 'tr', function() {});

这显然是一个非常简单的例子,但它应该足以构建一个好的模式。

顺便提一句,这是一件非常有趣的事情(至少对我来说.)若要检查被激发的事件,请执行以下操作:

代码语言:javascript
复制
$('table').on('click', 'tr', function(evt) {
   console.log(evt);
});

通过简单的点击或鼠标输入,查看事件携带了多少信息,以及从框中获取了多少有用的信息。

VanillaJs

当然,在没有任何库的情况下,也可以实现相同的结果。

使用Vanilla JS的一个简单实现可以从David Walsh的文章中摘自答案的开头链接,大致如下:

代码语言:javascript
复制
// 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>)中。

要开始的一个粗略实现如下所示:

代码语言:javascript
复制
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');
  }
})

请参阅此小提琴或下面的代码段:

代码语言:javascript
复制
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');
  }
})
代码语言:javascript
复制
table {
  width: 100%;
}
tr {
  background: #ddd;
}
.clicked {
  background: teal;
}
代码语言:javascript
复制
 <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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29004245

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档