1.什么是事件
事件(Event)是由 DOM 元素产生的资源,它可以由 JavaScript 代码操作。
在 Web 中,事件在浏览器窗口中被触发并且通常被绑定到窗口内部的特定部分 — 可能是一个元素、一系列元素、被加载到这个窗口的 HTML 代码或者是整个浏览器窗口。
例如:
- 用户在某个元素上点击鼠标或悬停光标
- 用户在键盘中按下某个按键
- 用户调整浏览器的大小或者关闭浏览器窗口
- 一个网页停止加载
- 提交表单
- 播放、暂停、关闭视频
- 发生错误
下面看一个例子:页面中只有一个 button按钮,按下时,背景会变成随机的一种颜色
HTML部分:
<button>Change color</button>
JavaScript部分:
const btn = document.querySelector('button');
function random(number) {
return Math.floor(Math.random()*(number+1));
}
btn.onclick = function() { // L0的事件监听写法
const randomColor = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
document.body.style.backgroundColor = randomColor;
}
解释:使用 btn 变量存储 button元素,并使用了Document.querySelector()
函数。同时定义了一个返回随机数字的函数。代码第三部分就是事件处理器。btn
变量指向 button 元素,在 button 这种对象上可触发一系列的事件,因此就可以使用事件处理器。我们通过将一个匿名函数(这个赋值函数包括生成随机色并赋值给背景色的代码)赋值给“点击”事件处理器参数,监听“点击”这个事件。从而只要点击事件在<button>元素上触发,该段代码就会被执行。即每当用户点击它时,都会运行此段代码。
2.事件流
概念:事件完整执行过程中的流动路径(包含捕获和冒泡)
2.1 事件对象
在事件处理函数内部,可能会出现一个固定指定名称的参数,例如event
,evt
或简单的e
。这被称为事件对象,它被自动传递给事件处理函数,以提供额外的功能和信息。
例如:
function bgChange(e) {
const randomColor = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
e.target.style.backgroundColor = randomColor ;
console.log(e);
}
btn.addEventListener('click', bgChange);
解释:在上面的函数中包括一个事件对象e
,并在函数中设置背景颜色样式在 e.target
上,事件对象 e
的 target
属性始终是事件刚刚发生的元素的引用。所以在这个例子中,我们在按钮上设置一个随机的背景颜色。
2.2 事件捕获
概念:从 DOM 的根元素开始去执行对应的事件(从外到里)
例如:DOM.addEventListener(事件类型,事件处理函数,是否使用捕获机制)
(其中第三个参数值为true或者false,默认为false代表冒泡阶段触发,true则代表是捕获阶段触发。)
2.3 事件冒泡
概念:当一个元素事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发,这个过程被称为事件冒泡。
简单理解:当一个元素触发事件时,会依次向上调用所有的父级元素的同名事件。
(注意:事件冒泡是默认存在的。)
例如:
HTML部分:
<div class="father">
<div class="son"></div>
</div>
CSS部分:
.father {
width: 500px;
height: 500px;
background-color: pink;
}
.son {
width: 200px;
height: 200px;
background-color: purple;
}
JavaScript部分:
const fa = document.querySelector('.father')
const son = document.querySelector('.son')
document.addEventListener('click', function () {
alert('我是爷爷')
})
fa.addEventListener('click', function () {
alert('我是爸爸')
})
son.addEventListener('click', function () {
alert('我是儿子')
})
解释,创建了两个div标签,依次监听事件并进行事件冒泡。当点击紫色div标签时,会从类名为son的事件的alert语句开始向上依次执行,从而依次显示:我是儿子,我是爸爸,我是爷爷。而点击粉色的div标签时,会从类名为father的alert语句依次向上执行,从而显示:我是爸爸,我是爷爷。
2.4 阻止冒泡
1.为什么要阻止冒泡
理由:因为默认有冒泡模式存在,所以容易导致事件影响父级,所以想要把事件限制在当前元素内,就要阻止冒泡。
2.语法
事件对象.stopPropagation();
注意:上述语法阻止的是流动传播,所以事件的捕获和冒泡都可以阻止。
例如:
const fa = document.querySelector('.father')
const son = document.querySelector('.son')
document.addEventListener('click', function () {
alert('我是爷爷')
})
fa.addEventListener('click', function () {
alert('我是爸爸')
})
son.addEventListener('click', function (e) {
alert('我是儿子')
// 阻止流动传播 事件对象.stopPropagation()
e.stopPropagation()
})
将事件冒泡的JavaScript部分给son的事件监听内加个事件对象e和函数e.stopPropagation(),就可以让son的事件不在向上执行,只执行“我是儿子”的输出。
2.5 事件委托
冒泡允许利用事件委托——这个概念依赖于这样一个事实,如果你想要在大量子元素中单击任何一个都可以运行一段代码,您可以将事件监听器设置在其父节点上,并让子节点上发生的事件冒泡到父节点上,而不是每个子节点单独设置事件监听器。
一个很好的例子是一系列列表项,如果你想让每个列表项被点击时弹出一条信息,您可以将click
单击事件监听器设置在父元素<ul>
上,这样事件就会从列表项冒泡到其父元素<ul>
上。
例如:
HTML部分:
<ul>
<li>第1个孩子</li>
<li>第2个孩子</li>
<li>第3个孩子</li>
<li>第4个孩子</li>
<li>第5个孩子</li>
<P>我不需要变色</P>
</ul>
JavaScript部分:
// 点击每个小li 当前li文字变为红色
// 按照事件委托方式
// 1.获得父元素
const ul = document.querySelector('ul')
ul.addEventListener('click',function(e){
// alert('11')
// this.style.color = 'red'
// e.target.style.color = 'red'
// console.dir(e.target)
if (e.target.tagName === 'LI'){
e.target.style.color = 'red'
}
})
3.结论:
事件并不是 JavaScript 的核心部分——它们是在浏览器 Web APIs 中定义的。理解 JavaScript 在不同环境下使用不同的事件模型十分重要。所以让我们一起学习,一起进步。谢谢大家的观看。