一、事件冒泡
在事件冒泡模式中,事件首先在目标元素上触发,然后逐级向上传播到包含该元素的父级元素,直到到达最外层的祖先元素。在事件冒泡过程中,每个包容元素的处理函数都会执行,如果有多个相同类型的事件处理函数,它们会按照绑定的先后顺序依次执行。
以下是一个简单的示例:
<div id="outer"> <div id="inner">Click me!</div> </div> <script> var outer = document.getElementById('outer'); var inner = document.getElementById('inner'); outer.addEventListener('click', function(event) { console.log('Clicked on outer element'); }); inner.addEventListener('click', function(event) { console.log('Clicked on inner element'); }); </script>
在上述代码中,当点击 inner 元素时,事件会首先在 inner 元素上触发,然后冒泡到 outer 元素,最终到达文档的根元素。
二、事件捕获
在事件捕获模式中,事件从最外层的祖先元素开始逐级向下传播,直到到达目标元素。在事件捕获过程中,每个包容元素的处理函数都会执行,如果有多个相同类型的事件处理函数,它们会按照绑定的先后顺序依次执行。
以下是一个简单的示例:
<div id="outer"> <div id="inner">Click me!</div> </div> <script> var outer = document.getElementById('outer'); var inner = document.getElementById('inner'); outer.addEventListener('click', function(event) { console.log('Clicked on outer element (capture)'); }, true); inner.addEventListener('click', function(event) { console.log('Clicked on inner element (capture)'); }, true); </script>
在上述代码中,当点击 inner 元素时,事件从 outer 元素开始向下传播,在捕获阶段依次触发 outer 和 inner 元素的事件处理函数,最终到达目标元素 inner。
三、事件传播的应用
在实际开发中,我们可以利用事件冒泡和捕获的特性来实现一些常见的任务。
例如,在使用表格布局时,我们可能需要根据用户的操作来调整表格列宽。可以通过在表格父元素上绑定 mousemove 事件来实现:
<table> <thead> <tr> <th>Column 1</th> <th>Column 2</th> <th>Column 3</th> </tr> </thead> <tbody> <tr> <td>Content 1-1</td> <td>Content 1-2</td> <td>Content 1-3</td> </tr> <tr> <td>Content 2-1</td> <td>Content 2-2</td> <td>Content 2-3</td> </tr> </tbody> </table> <script> var table = document.querySelector('table'); var resizing = false; var column = null; var startX = null; table.addEventListener('mousedown', function(event) { if (event.target.tagName === 'TH') { resizing = true; column = event.target; startX = event.pageX; } }, true); table.addEventListener('mousemove', function(event) { if (resizing) { var deltaX = event.pageX - startX; var width = parseInt(column.style.width || column.clientWidth); column.style.width = (width + deltaX) + 'px'; startX = event.pageX; } }, true); table.addEventListener('mouseup