一、事件冒泡
在事件冒泡模式中,事件首先在目标元素上触发,然后逐级向上传播到包含该元素的父级元素,直到到达最外层的祖先元素。在事件冒泡过程中,每个包容元素的处理函数都会执行,如果有多个相同类型的事件处理函数,它们会按照绑定的先后顺序依次执行。
以下是一个简单的示例:
<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