事件是由用户或浏览器本身发起的发生在浏览器中的动作。以下示例为发生在网站上的一些常见事件:
页面完成加载
用户点击按钮
用户将鼠标悬停在下拉菜单上
用户提交表单
用户按下键盘上的键
通过编写执行事件的JavaScript响应代码,开发人员可以向用户显示消息、验证数据、对按钮单击做出反应以及许多其他操作。
本文将介绍事件处理程序、事件侦听器和事件对象。还将介绍三种不同的方式来处理事件,以及一些最常见的事件。了解事件可以帮助开发人员为用户提供更具交互性的web体验。
当用户单击按钮或按下某个键时,会触发事件。分别称为点击事件和按键事件。
事件处理程序是在事件触发时运行的JavaScript函数。
事件侦听器附加响应式接口到元素,允许特定元素等待并“侦听”给定事件的触发。
将事件分配给元素的三种方法:
内联事件处理程序
事件处理程序属性
事件监听器
下面我们将一一介绍这三种方法的优缺点。
要学习事件处理程序,首先要了解内联事件处理程序。让我们从一个由button
元素和p
元素组成的基本示例开始:用户单击按钮时更改p
的文本内容。
events.html
- <!DOCTYPE html>
- <html lang="en-US">
-
- <head>
- <title>Events</title>
- </head>
-
- <body>
-
- <!-- Add button -->
- <button>Click me</button>
-
- <p>Try to change me.</p>
-
- </body>
-
- <!-- Reference JavaScript file -->
- <script src="js/events.js"></script>
-
- </html>
直接在按钮上添加onclick
属性。属性值是我们创建的名为changeText()
的函数。
events.html
- <!DOCTYPE html>
- <html lang="en-US">
-
- <head>
- <title>Events</title>
- </head>
-
- <body>
-
- <button onclick="changeText()">Click me</button>
-
- <p>Try to change me.</p>
-
- </body>
-
- <script src="js/events.js"></script>
-
- </html>
创建events.js
文件,并放在此处的js/
目录中。再创建changeText()
函数,用于修改p
元素的textContent
。
js/events.js
- // Function to modify the text content of the paragraph
- const changeText = () => {
- const p = document.querySelector('p');
-
- p.textContent = "I changed because of an inline event handler.";
- }
首次加载events.html
时,你可以看到如下所示的页面:
单击按钮,p
元素的文本将“Try to change me”更改为“I changed because of an inline event handler.”:
内联事件处理程序有助于直接理解事件,但通常用于测试和教学演示,正式项目中不推荐使用。
事件处理程序属性与内联处理程序非常相似,除了一点,我们在JavaScript中设置元素的属性,而不是在HTML中设置属性。
此处的设置相同,只是不再在标记中包含onclick="changeText()"
:
events.html
- ...
- <body>
-
- <button>Click me</button>
-
- <p>I will change.</p>
-
- </body>
- ...
函数也相似,除了现在需要访问的是JavaScript中的button
元素。我们可以像访问style
或id
或任何其他元素属性一样访问onclick
,然后分配函数引用。
js/events.js
- / Function to modify the text content of the paragraph
- const changeText = () => {
- const p = document.querySelector('p');
-
- p.textContent = "I changed because of an event handler property.";
- }
-
- // Add event handler as a property of the button element
- const button = document.querySelector('button');
- button.onclick = changeText;
注意:事件处理程序不遵循大多数JavaScript代码所遵循的
驼峰式命名
规则。注意是onclick
,而不是onClick
。
首次加载页面时,浏览器将显示以下内容:
现在单击按钮,将实现与之前类似的效果:
注意,在将函数引用传递给
onclick
属性时,不包括括号,因为此时并没有调用函数,只是传递了对它的引用。
事件处理程序属性比内联处理程序更易于维护,但仍然受制于一些相同的障碍。例如,尝试设置多个单独的onclick
属性将导致除最后一个之外的所有属性都被覆盖,如下所示。
js/events.js
- const p = document.querySelector('p');
- const button = document.querySelector('button');
-
- const changeText = () => {
- p.textContent = "Will I change?";
- }
-
- const alertText = () => {
- alert('Will I alert?');
- }
-
- // Events can be overwritten
- button.onclick = changeText;
- button.onclick = alertText;
在上面的示例中,单击button
只会弹出提示框,不会更改p
元素的文本,因为alert()
是最后一个添加到onclick
属性中的。
事件侦听器监视元素上的事件。我们将使用addEventListener()
方法来侦听事件,而并不是将事件直接分配给元素上的属性。
addEventListener()
有两个必要参数——要监听的事件和监听器回调函数。
事件侦听器的HTML将与前面的示例相同。
events.html
- ...
- <button>Click me</button>
-
- <p>I will change.</p>
- ...
我们仍将使用与之前相同的changeText()
函数。将addEventListener()
方法附加到按钮上。
js/events.js
- // Function to modify the text content of the paragraph
- const changeText = () => {
- const p = document.querySelector('p');
-
- p.textContent = "I changed because of an event listener.";
- }
-
- // Listen for click event
- const button = document.querySelector('button');
- button.addEventListener('click', changeText);
注意,在前两种方法中,点击事件被称为
onclick
,但在事件侦听器中,被称为click
。每个事件侦听器都会剔除单词中的on
。
使用上面的JavaScript代码重新加载页面,将收到以下输出:
乍一看,事件侦听器似乎与事件处理程序属性非常相似,但事件侦听器有一些优点。我们可以在同一个元素上设置多个事件监听器,如下例所示。
js/events.js
- const p = document.querySelector('p');
- const button = document.querySelector('button');
-
- const changeText = () => {
- p.textContent = "Will I change?";
- }
-
- const alertText = () => {
- alert('Will I alert?');
- }
-
- // Multiple listeners can be added to the same event and element
- button.addEventListener('click', changeText);
- button.addEventListener('click', alertText);
上面的两个事件都将触发:首先弹出提示框,一旦点击关闭提示框后便修改p
元素的内容。
通常,我们使用匿名函数替代事件侦听器上的函数引用。匿名函数是未命名的函数。
- // An anonymous function on an event listener
- button.addEventListener('click', () => {
- p.textContent = "Will I change?";
- });
我们也可以使用removeEventListener()
函数从元素中删除一个或所有事件。
- // Remove alert function from button element
- button.removeEventListener('click', alertText);
此外,还可以在document
和window
对象上使用addEventListener()
。
事件侦听器是目前在JavaScript中处理事件最常用的首选方式。
除了内联事件处理程序、事件处理程序属性和事件侦听器,JavaScript中还有更多事件。下面我们将讨论一些最常见的事件。
鼠标事件是最常用的事件之一,指的是涉及单击鼠标按钮、悬停和移动鼠标的事件。这些事件也对应于触摸设备上的等效操作。
事件 | 描述 |
---|---|
click | 在元素上按下和释放鼠标时触发 |
dblclick | 双击元素时触发 |
mouseenter | 当鼠标进入元素时触发 |
mouseleave | 当鼠标离开元素时触发 |
mousemove | 每当鼠标在元素内移动时触发 |
click
是一个复合事件,由mousedown
和mouseup
事件组合而成,分别在按下或抬起鼠标按钮时触发。
使用mouseenter
和mouseleave
之后将重新创建悬停效果,只要鼠标指针位于元素上,效果就会持续。
表单事件是与表单相关的操作,例如选择或取消选择input
元素以及提交表单。
事件 | 描述 |
---|---|
submit | 提交表单时触发 |
focus | 当元素获得焦点时触发 |
blur | 当元素失去焦点时触发 |
当元素被选中时,例如,通过鼠标单击或TAB键导航到元素时,将获得焦点。
使用JavaScript发送表单的优点是提交表单时不需要重新加载页面,并且可以使用JavaScript来验证所需的输入字段。
键盘事件用于处理键盘动作,例如按下键、抬起键和按住键。
事件 | 描述 |
---|---|
keydown | 按下键时触发一次 |
keyup | 释放键时触发一次 |
keypress | 按下键时连续触发 |
虽然键盘事件看起来很相似,但keydown
和keypress
事件访问的键并不所有完全相同。keydown
将确认按下的每个键,而keypress
将忽略不产生字符的键,例如SHIFT
、ALT
以及DELETE
。
键盘事件具有访问单个键的特定属性。
假如将一个参数,例如event
对象,传递给事件侦听器,那么我们可以访问有关所发生操作的更多信息。与键盘对象相关的两个属性包括key
和code
。
例如,如果用户按下键盘上的字母a
键,则与该键相关的以下属性将浮出水面:
属性 | 描述 | 示例 |
---|---|---|
key | 表示字符名称 | a |
code | 表示被按下的物理键 | KeyA |
为了展示如何通过JavaScript控制台收集这些信息,我们编写以下代码行。
- // Test the key and code properties
- document.addEventListener('keydown', event => {
- console.log('key: ' + event.key);
- console.log('code: ' + event.code);
- });
一旦我们在控制台按下ENTER
键,就可以在键盘上按键,在本例中,按的是a
。
- Output
- key: a
- code: KeyA
key
属性是字符的名称,可以改变——例如,按下SHIFT
和a
会变成A
。而code
属性表示的是键盘上的物理键。
Event对象由所有事件都可以访问的属性和方法组成。除了通用的Event对象外,每种类型的事件都各有扩展,例如KeyboardEvent
和MouseEvent
。
Event对象通过侦听器函数作为参数传递,通常写作event
或e
。我们可以访问keydown
事件的code
属性来复制PC游戏的键盘控件。
创建一个带有<p>
标记的基本HTML文件并将其加载到浏览器中。
event-test-p.html
- <!DOCTYPE html>
- <html lang="en-US">
- <head>
- <title>Events</title>
- </head>
- <body>
-
- <p></p>
-
- </body>
- </html>
然后,在浏览器的开发者控制台中输入以下JavaScript代码。
- // Pass an event through to a listener
- document.addEventListener('keydown', event => {
- var element = document.querySelector('p');
-
- // Set variables for keydown codes
- var a = 'KeyA';
- var s = 'KeyS';
- var d = 'KeyD';
- var w = 'KeyW';
-
- // Set a direction for each code
- switch (event.code) {
- case a:
- element.textContent = 'Left';
- break;
- case s:
- element.textContent = 'Down';
- break;
- case d:
- element.textContent = 'Right';
- break;
- case w:
- element.textContent = 'Up';
- break;
- }
- });
当你按下其中一个键(a
、s
、d
或w
)时,将看到类似以下内容的输出:
接下来,你可以继续开发浏览器如何响应以及用户按下这些键的方式,创建一个更加动态的网站。
继续介绍最常用的事件属性之一:target
属性。在下面的示例中,在section
中有三个div
元素。
event-test-div.html
- <!DOCTYPE html>
- <html lang="en-US">
- <head>
- <title>Events</title>
- </head>
- <body>
-
- <section>
- <div id="one">One</div>
- <div id="two">Two</div>
- <div id="three">Three</div>
- </section>
-
- </body>
- </html>
通过在浏览器的开发者控制台中使用event.target
,我们可以将事件侦听器放置在外部section
元素上,并获取嵌套最深的元素。
- const section = document.querySelector('section');
-
- // Print the selected target
- section.addEventListener('click', event => {
- console.log(event.target);
- });
单击其中任何一个元素都会返回相关特定元素的输出到控制台。这非常有用,因为你只需要放置一个事件侦听器,就可以访问许多嵌套元素。
事件是发生在网站上的操作,例如单击、悬停、提交表单、加载页面或按下键盘上的键。当我们能够让网站响应用户采取的行动时,JavaScript才真正变得交互性和动态性。
本文结束!感谢大家的阅读!