专业编程基础技术教程

网站首页 > 基础教程 正文

前端面试:每日一题(2)

ccvgpt 2024-08-29 13:15:45 基础教程 10 ℃

事件委托代理

在构建应用程序时,有时需要将事件绑定到页面上的按钮、文本或图像,以便在用户与元素交互时执行某些操作。

如果我们以一个简单的待办事项列表为例,面试官可能会告诉你,当用户点击列表中的一个列表项时执行某些操作。他们希望你用 JavaScript 实现这个功能,假设有如下 HTML 代码:

前端面试:每日一题(2)

<ul id="todo-app">
 <li class="item">Walk the dog</li>
 <li class="item">Pay bills</li>
 <li class="item">Make dinner</li>
 <li class="item">Code for one hour</li>
</ul>

你可能想要做如下操作来将事件绑定到元素:

document.addEventListener('DOMContentLoaded', function() {
 let app = document.getElementById('todo-app');
 let itimes = app.getElementsByClassName('item');
 for (let item of items) {
 item.addEventListener('click', function(){
 alert('you clicked on item: ' + item.innerHTML);
 })
 }
})

虽然这在技术上是可行的,但问题是要将事件分别绑定到每个项,这对于目前 4 个元素来说,没什么大问题,但是如果在待办事项列表中添加了 10,000 项(他们可能有很多事情要做)怎么办?

如果用函数创建 10,000 个独立的事件侦听器,并将每个事件监听器绑定到 DOM ,这样代码执行的效率非常低下。

在面试中,最好先问面试官用户可以输入的最大元素数量是多少。例如,如果它不超过 10,那么上面的代码就可以很好地工作。但是如果用户可以输入的条目数量没有限制,那么你应该使用一个更高效的解决方案。

如果你的应用程序最终可能有数百个事件侦听器,那么更有效的解决方案是将一个事件侦听器实际绑定到整个容器,然后在单击它时能够访问每个列表项, 这称为 事件委托,它比附加单独的事件处理程序更有效。

注意事项:

  1. 事件委托发生在冒泡阶段
  2. addEventListener方法第三个参数默认为false,也就是允许冒泡
  3. 在dom上直接绑定的事件,事件会处于“目标阶段”。在目标阶段的事件会触发该元素(即事件目标)上的所有监听器,而不在乎这个监听器到底在注册时useCapture 参数值是true还是false。

下面是事件委托的代码:

document.addEventListener('DOMContentLoaded', function() {
 let app = document.getElementById('todo-app');
 app.addEventListener('click', function(e) {
 if (e.target && e.target.nodeName === 'LI') {
 let item = e.target;
 alert('you clicked on item: ' + item.innerHTML)
 }
 })
})

最近发表
标签列表