JavaScript 事件

摘要:在本教程中,您将了解 JavaScript 事件、事件模型以及如何处理事件。

JavaScript 事件简介

事件是 Web 浏览器可以检测和响应的操作,例如鼠标点击或页面加载。

例如,您可能希望在用户点击按钮时显示警报。

事件可能有一个事件处理程序,即在事件发生时运行的函数。事件处理程序,也称为事件侦听器,侦听事件并在事件发生时执行。

假设您有一个 id 为 btn 的按钮

<button id="btn">Click Me!</button>Code language: HTML, XML (xml)

要定义一个在点击按钮时将执行的函数,您需要使用 addEventListener() 方法注册一个事件处理程序

let btn = document.querySelector('#btn');

function handleClick() {
    alert('It was clicked!');
}

btn.addEventListener('click', handleClick);Code language: JavaScript (javascript)

它是如何工作的。

  • 首先,使用 querySelector() 方法选择 id 为 btn 的按钮。
  • 其次,定义一个名为 handleClick()函数 作为事件处理程序。
  • 第三,使用 addEventListener() 注册事件处理程序,以便当用户点击按钮时,display() 函数将执行。

注册事件处理程序的更短方法是将所有代码放在一个 匿名函数 中,如下所示

let btn = document.querySelector('#btn');

btn.addEventListener('click',function() {
    alert('It was clicked!');
});Code language: JavaScript (javascript)

或者,您可以使用 箭头函数

let btn = document.querySelector('#btn');

btn.addEventListener('click',() => {
    alert('It was clicked!');
});Code language: JavaScript (javascript)

事件流

假设您有以下 HTML 文档

<!DOCTYPE html>
<html>
<head>
    <title>JS Event Demo</title>
</head>
<body>
    <div id="container">
        <button id='btn'>Click Me!</button>
    </div>
</body>Code language: HTML, XML (xml)

当您点击按钮时,点击事件不仅发生在按钮上,还会发生在按钮的容器 div 和整个网页上。

事件流解释了从事件发生的元素开始,并通过 DOM 树传播到页面的顺序。

主要有两种事件模型

  • 事件冒泡
  • 事件捕获

事件冒泡

在事件冒泡模型中,事件从最具体的元素开始,然后向上流向最不具体的元素(document 甚至 window)。

当您点击按钮时,click 事件按以下顺序发生

  1. 按钮
  2. id 为 container 的 div
  3. 身体
  4. html
  5. 文件

click 事件首先发生在被点击的元素按钮上。然后,click 事件沿着 DOM 树向上移动,在其路径上的每个节点上触发,直到到达 document 对象。

下图说明了用户点击按钮时的事件冒泡效果

JavaScript event bubbling

请注意,现代 Web 浏览器将事件冒泡到 window 对象。

事件捕获

在事件捕获模型中,事件从最不具体的元素开始,并向下流向最具体的元素。

当您点击按钮时,click 事件按以下顺序发生

  1. 文件
  2. html
  3. 身体
  4. id 为 container 的 div
  5. 按钮

下图说明了事件捕获效果

JavaScript event capturing

DOM Level 2 事件流

DOM level 2 事件指定事件流有三个阶段

  • 首先,发生事件捕获,这提供了拦截事件的机会。
  • 然后,实际目标接收事件。
  • 最后,发生事件冒泡,允许对事件进行最终响应。

下图说明了用户点击按钮时的 DOM Level 2 事件模型

JavaScript DOM Level 2 Event

事件对象

当事件发生时,Web 浏览器将一个 Event 对象传递给事件处理程序

let btn = document.querySelector('#btn');

btn.addEventListener('click', function(event) {
    console.log(event.type);
});Code language: JavaScript (javascript)

输出

'click'Code language: JavaScript (javascript)

下表显示了 event 对象最常用的属性和方法

属性/方法描述
气泡如果事件冒泡,则为真
可取消如果可以取消事件的默认行为,则为真
当前目标事件正在触发的当前元素
defaultPrevented如果调用了 preventDefault(),则返回 true。
详细信息有关事件的更多信息
eventPhase捕获阶段为 1,目标为 2,冒泡为 3
preventDefault()取消事件的默认行为。此方法仅在 cancelable 属性为 true 时有效
stopPropagation()取消任何进一步的事件捕获或冒泡。此方法仅在 bubbles 属性为 true 时可以使用。
目标事件的目标元素
类型触发的事件类型

请注意,event 对象只能在事件处理程序内访问。一旦所有事件处理程序都执行完毕,事件对象就会自动销毁。

preventDefault()

要阻止事件的默认行为,您使用 preventDefault() 方法。

例如,当您点击链接时,浏览器会将您导航到 href 属性中指定的 URL

<a href="https://tutorial.javascript.ac.cn/">JS Tutorial</a>Code language: HTML, XML (xml)

但是,您可以使用 event 对象的 preventDefault() 方法来阻止这种行为

let link = document.querySelector('a');

link.addEventListener('click',function(event) {
    console.log('clicked');
    event.preventDefault();
});Code language: JavaScript (javascript)

请注意,preventDefault() 方法不会阻止事件向上冒泡 DOM。当事件的 cancelable 属性为 true 时,可以取消事件。

stopPropagation()

stopPropagation() 方法会立即停止事件通过 DOM 树的传播。但是,它不会阻止浏览器的默认行为。

请参见以下示例

let btn = document.querySelector('#btn');

btn.addEventListener('click', function(event) {
    console.log('The button was clicked!');
    event.stopPropagation();
});

document.body.addEventListener('click',function(event) {
    console.log('The body was clicked!');
});
Code language: JavaScript (javascript)

如果没有 stopPropagation() 方法,您将在控制台窗口中看到两条消息。

但是,click 事件永远不会到达 body,因为在按钮的 click 事件处理程序上调用了 stopPropagation()

总结

  • 事件是 Web 浏览器中发生的事件,例如鼠标点击。
  • 事件流有两种主要模型:事件冒泡和事件捕获。
  • DOM Level 2 事件指定事件流有三个阶段:事件冒泡、事件发生在确切的元素上以及事件捕获。
  • 使用 addEventListener() 注册一个将事件连接到事件侦听器的事件
  • event 对象只能在事件侦听器内访问。
  • 使用 preventDefault() 方法来阻止事件的默认行为,但不会阻止事件流。
  • 使用 stopPropagation() 方法来阻止事件通过 DOM 树的传播,但不会取消浏览器的默认行为。

测验

本教程是否有用?