一、事件流
-
捕获
-
描述:
在 JavaScript 中,事件捕获是从 DOM 树的根节点开始,向目标元素依次传递事件的过程。例如,假设我们有以下 HTML 结构:
-
<div id="outer">
<div id="inner">
<button id="btn">点击我</button>
</div>
</div>
如果我们在window对象上添加一个click事件监听器,并设置useCapture参数为true,当点击#btn按钮时,事件首先会在window上触发(假设没有其他更外层元素),然后依次传递到#outer、#inner,最后到达#btn。
window.addEventListener('click', function() {
console.log('window捕获');
}, true);
document.getElementById('outer').addEventListener('click', function() {
console.log('outer捕获');
}, true);
document.getElementById('inner').addEventListener('click', function() {
console.log('inner捕获');
}, true);
document.getElementById('btn').addEventListener('click', function() {
console.log('btn捕获');
}, true);
-
事件冒泡
-
描述:
事件冒泡是从目标元素开始,沿着 DOM 树向上传播事件。以刚才的 HTML 结构为例,当我们给#btn添加一个click事件监听器(不设置useCapture,默认为false,即冒泡阶段处理),然后点击#btn,事件首先在#btn上触发,接着冒泡到#inner、#outer,如果有window上的冒泡阶段的click事件监听器,也会触发。
-
document.getElementById('btn').addEventListener('click', function() {
console.log('btn冒泡');
});
document.getElementById('inner').addEventListener('click', function() {
console.log('inner冒泡');
});
document.getElementById('outer').addEventListener('click', function() {
console.log('outer冒泡');
});
window.addEventListener('click', function() {
console.log('window冒泡');
});
-
阻止冒泡
-
描述:
在事件处理函数中,可以使用event.stopPropagation()方法来阻止事件冒泡。例如,我们不希望#btn的click事件冒泡到#inner,可以这样做:
-
document.getElementById('btn').addEventListener('click', function(event) {
console.log('btn点击,阻止冒泡');
event.stopPropagation();
});
二、事件委托
-
得到子元素
-
描述:
假设我们有一个<ul>列表,里面有多个<li>元素。我们将click事件绑定到<ul>上,在事件处理函数中通过event.target获取实际被点击的<li>元素。
-
<ul id="myList">
<li>列表项1</li>
<li>列表项2</li>
<li>列表项3</li>
</ul>
document.getElementById('myList').addEventListener('click', function(event) {
if (event.target.tagName === 'LI') {
console.log('点击了列表项: ', event.target.textContent);
}
});
-
事件委托案例练习
-
练习内容:
有一个<ul>列表,里面有若干个<li>元素,每个<li>元素都有一个不同颜色的背景(通过内联样式设置)。要求使用事件委托,当点击某个<li>时,将其背景颜色设置为红色。 -
解答:
-
<ul id="colorList">
<li style="background - color: blue;">蓝色背景项</li>
<li style="background - color: green;">绿色背景项</li>
<li style="background - color: yellow;">黄色背景项</li>
</ul>
document.getElementById('colorList').addEventListener('click', function(event) {
if (event.target.tagName === 'LI') {
event.target.style.backgroundColor = 'red';
}
});
三、阻止默认行为
-
描述
-
在 JavaScript 中,许多 HTML 元素都有默认行为。例如,
<a>标签默认会跳转到其href属性指定的链接。如果我们想阻止这种默认行为,可以在<a>标签的click事件处理函数中使用event.preventDefault()。
-
<a href="https://www.example.com" id="myLink">示例链接</a>
document.getElementById('myLink').addEventListener('click', function(event) {
console.log('点击了链接,但阻止跳转');
event.preventDefault();
});
四、事件解绑
-
案例练习
-
练习内容:
有一个按钮<button id="myButton">点击我</button>,当页面加载时,给按钮添加一个click事件处理函数,该函数在按钮被点击时在控制台输出一条消息。当按钮被点击两次后,解除该按钮的click事件处理函数。 -
解答:
-
<button id="myButton">点击我</button>
let clickCount = 0;
const button = document.getElementById('myButton');
const clickHandler = function() {
console.log('按钮被点击了');
clickCount++;
if (clickCount === 2) {
button.removeEventListener('click', clickHandler);
}
};
button.addEventListener('click', clickHandler);
五、其他事件
-
页面加载事件
-
事件名:load
-
描述:
load事件在整个页面(包括所有资源,如图片、样式表等)都加载完成后触发。例如,我们有一个页面包含一张图片,当图片和页面所有内容都加载完后执行一个函数。
-
-
<img src="example.jpg" alt="示例图片">
window.addEventListener('load', function() {
console.log('页面和所有资源加载完成');
});
-
事件名:DOMContentLoaded
-
描述:
DOMContentLoaded事件在 HTML 文档被完全解析和加载(DOM 树构建完成)后触发,但不等待样式表、图片等外部资源加载完成。
-
<script>
document.addEventListener('DOMContentLoaded', function() {
console.log('DOM树构建完成');
});
</script>
六、元素滚动事件
-
案例练习
-
案例内容:
有一个长页面,页面中有一个固定位置的导航栏,当页面滚动到一定位置时,希望导航栏的背景颜色从透明变为不透明,以增强可读性。 -
分析:
首先,需要监听页面的滚动事件,可以使用window.addEventListener('scroll', function() {...})。在滚动事件处理函数中,获取页面的滚动距离(可以通过window.scrollY获取)。当滚动距离达到某个阈值(例如 200px)时,改变导航栏的背景颜色。
-
<nav id="myNav">导航栏</nav>
<div style="height:1000px;">一些内容,用于滚动</div>
const navBar = document.getElementById('myNav');
window.addEventListener('scroll', function() {
if (window.scrollY > 200) {
navBar.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
} else {
navBar.style.backgroundColor = 'transparent';
}
});
七、页面尺寸事件
-
描述
-
页面尺寸事件主要用于处理浏览器窗口大小改变的情况。在 JavaScript 中,可以使用
window.addEventListener('resize', function() {...})来监听窗口大小的改变。例如,当窗口大小改变时,我们可以调整页面中某个元素的大小。假设我们有一个<div>元素,我们希望它的宽度始终是窗口宽度的一半。
-
<div id="myDiv" style="height:100px;"></div>
const div = document.getElementById('myDiv');
window.addEventListener('resize', function() {
div.style.width = window.innerWidth / 2 + 'px';
});
八、元素尺寸与位置
-
案例练习
-
练习内容:
有一个<div>元素,在页面加载完成后,计算并在控制台输出该<div>元素的宽度、高度、相对于页面左上角的水平位置和垂直位置。 -
解答:
-
<div id="myDiv" style="width:200px; height:150px; margin - left:50px; margin - top:30px;"></div>
window.addEventListener('load', function() {
const div = document.getElementById('myDiv');
console.log('宽度: ', div.offsetWidth);
console.log('高度: ', div.offsetHeight);
console.log('水平位置: ', div.offsetLeft);
console.log('垂直位置: ', div.offsetTop);
});