MST

星途 面试题库

面试题:JavaScript事件委托中函数的动态绑定与性能优化

假设有一个包含大量列表项(`<li>`元素)的无序列表(`<ul>`),其id为'list'。现在需要为每个列表项添加点击事件处理函数,当点击某个列表项时,在控制台输出该项的文本内容。请使用事件委托的方式实现,并阐述如何优化性能,避免在大量列表项时的性能问题。同时说明在事件委托过程中,函数动态绑定的原理及可能遇到的坑。
25.3万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

实现代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
</head>

<body>
    <ul id="list">
        <li>列表项1</li>
        <li>列表项2</li>
        <li>列表项3</li>
        <!-- 大量列表项 -->
    </ul>
    <script>
        const list = document.getElementById('list');
        list.addEventListener('click', function (event) {
            if (event.target.tagName === 'LI') {
                console.log(event.target.textContent);
            }
        });
    </script>
</body>

</html>

性能优化

  1. 减少事件绑定数量:通过事件委托,只在父元素ul上绑定一个点击事件,而不是为每个li元素分别绑定事件,这样可以显著减少内存占用和事件处理开销。
  2. 合理使用事件冒泡:利用事件冒泡机制,事件从触发的li元素向上冒泡到ul元素,ul元素捕获到事件后再进行处理。这样无论有多少个li元素,都只需要处理一次事件。

函数动态绑定原理

  1. 事件冒泡:事件从触发的目标元素开始,逐层向上传播到祖先元素。在事件委托中,父元素通过监听特定类型的事件(如click),利用事件冒泡机制来捕获子元素触发的相同类型事件。
  2. 目标判断:在父元素的事件处理函数中,通过判断event.target来确定实际触发事件的目标元素。如果目标元素是我们期望处理的元素(如li元素),则执行相应的处理逻辑。

可能遇到的坑

  1. 事件冒泡干扰:如果在子元素中有阻止事件冒泡的操作(如event.stopPropagation()),会导致父元素无法捕获到事件,从而使事件委托失效。
  2. 误判目标元素:在事件处理函数中判断event.target时,要确保判断准确。例如,如果li元素内部还有其他子元素,可能会因为event.target是子元素而导致误判,需要准确判断event.targettagName等属性。
  3. 动态添加元素:如果列表项是动态添加的,需要注意事件委托的绑定时机。如果在添加新元素之前没有绑定事件委托,新添加的元素将不会触发委托的事件。可以在页面加载完成后或动态添加元素的逻辑中,确保事件委托绑定在父元素上。