介绍
在了解DOM系列中,我们讨论了DOM树以及如何使用开发人员工具控制台 访问 , 遍历 , 添加和删除以及修改节点和元素。
尽管在这一点上,我们现在可以对DOM所做的任何更改进行修改,但从用户角度来看,它并不是非常有用,因为我们只手动触发更改。 通过了解事件,我们将了解如何将所有事情联系在一起以制作互动网站。
事件是在浏览器中发生的操作,可以由用户或浏览器本身启动。 以下是一些可能发生在网站上的常见事件的例子:
- 该页面完成加载
- 用户点击一个按钮
- 用户悬停在下拉列表中
- 用户提交表单
- 用户按下键盘上的按键
通过对事件执行的JavaScript响应进行编码,开发人员可以向用户显示消息,验证数据,响应按钮点击以及其他许多操作。
在本文中,我们将介绍事件处理程序,事件监听器和事件对象。 我们还将通过三种不同的方式编写代码来处理事件,以及一些最常见的事件。 通过了解事件,您可以为最终用户提供更具互动性的网络体验。
事件处理程序和事件监听器
当用户点击一个按钮或按下某个键时,会触发一个事件。 这些分别称为点击事件或按键事件。
事件处理程序是一个JavaScript函数,在事件触发时运行。
一个事件监听器将一个响应接口附加到一个元素上,该元素允许该特定元素等待并“监听”给定事件触发。
有三种方法可以将事件分配给元素:
- 内联事件处理程序
- 事件处理器属性
- 事件监听器
我们将通过三种方法来确保您熟悉事件触发的每种方式,然后讨论每种方法的优缺点。
内联事件处理程序属性
要开始了解事件处理程序,我们将首先考虑内联事件处理程序 。 让我们从一个非常基本的例子开始,它由一个button
元素和一个p
元素组成。 我们希望用户单击button
来更改p
的文本内容。
我们从一个带有按钮的HTML页面开始。 我们将引用一个JavaScript文件,我们稍后将添加代码。
<!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>
直接在button
,我们将添加一个名为onclick
的属性。 属性值将是我们创建的名为changeText()
的函数。
<!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
。
// Function to modify the text content of the paragraphconst 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.
, I changed because of an inline event handler.
:
内联事件处理程序是开始理解事件的直接方式,但它们通常不应超出测试和教育目的。
您可以比较内联事件处理程序以在HTML元素上嵌入CSS样式。 维护一个单独的类样式表比在每个元素上创建内联样式要实用得多,正如维护完全通过单独的脚本文件处理JavaScript而不是为每个元素添加处理程序一样。
事件处理程序属性
内联事件处理程序的下一步是事件处理程序属性 。 这与内联处理程序非常类似,只不过我们使用JavaScript设置元素的属性而不是HTML中的属性。
除了我们不再在标记中包含onclick="changeText()"
之外,这里的设置将与此相同:
...<body> <button>Click me</button> <p>I will change.</p></body>...
我们的函数也会保持相似,除了现在我们需要访问JavaScript中的button
元素。 我们可以简单地访问onclick
就像访问style
或id
或任何其他元素属性一样,然后分配函数引用。
// Function to modify the text content of the paragraphconst 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 elementconst button = document.querySelector('button');button.onclick = changeText;
注:事件处理程序不遵循大多数JavaScript代码遵循的camelCase约定。 请注意,该代码是onclick
,而不是onClick
。
当您第一次加载页面时,浏览器将显示以下内容:
现在当你点击这个按钮时,它会有和以前一样的效果:
请注意,将函数引用传递给onclick
属性时,我们不包括括号,因为我们在那一刻不调用该函数,而只是传递对它的引用。
事件处理程序属性比内联处理程序稍微更易维护,但它仍然遭受一些相同的障碍。 例如,尝试设置多个独立的onclick
属性会导致除最后一个之外的所有其他内容被覆盖,如下所示。
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 overwrittenbutton.onclick = changeText;button.onclick = alertText;
在上面的例子中, button
点击只会显示一个提醒,并且不会改变p
文本,因为alert()
代码是最后一个添加到属性的代码。
了解内联事件处理程序和事件处理程序属性后,让我们转到事件监听器。
事件监听器
JavaScript事件处理程序的最新成员是事件监听器。 事件监听器监视元素上的事件。 我们将使用addEventListener()
方法来监听事件,而不是直接将事件分配给元素上的属性。
addEventListener()
需要两个必需参数 – 它要监听的事件和监听器回调函数。
我们的事件监听器的HTML将和前面的例子一样。
... <button>Click me</button> <p>I will change.</p>...
我们仍将使用与之前相同的changeText()
函数。 我们将addEventListener()
方法附加到按钮上。
// Function to modify the text content of the paragraphconst changeText = () => { const p = document.querySelector('p'); p.textContent = "I changed because of an event listener.";}// Listen for click eventconst button = document.querySelector('button');button.addEventListener('click', changeText);
请注意,前两种方法中,点击事件被称为onclick
,但事件监听器称为click
。 每个事件监听者都会从单词中删除。 在下一节中,我们将看到更多其他类型事件的例子。
当您使用上面的JavaScript代码重新加载页面时,您会收到以下输出:
首先看,事件监听器看起来与事件处理器属性非常相似,但它们有一些优点。 我们可以在同一个元素上设置多个事件监听器,如下例所示。
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 elementbutton.addEventListener('click', changeText);button.addEventListener('click', alertText);
在这个例子中,两个事件都会触发,一旦点击了警报,就为用户提供了警报和修改后的文本。
通常,将使用匿名函数而不是事件监听器的函数引用。 匿名函数是没有命名的函数。
// An anonymous function on an event listenerbutton.addEventListener('click', () => { p.textContent = "Will I change?";});
也可以使用removeEventListener()
函数从元素中删除一个或全部事件。
// Remove alert function from button elementbutton.removeEventListener('click', alertText);
此外,您可以在document
和window
对象上使用addEventListener()
。
事件监听器是当前处理JavaScript中事件的最常见和首选的方式。
常见事件
我们已经使用click事件了解了内联事件处理程序,事件处理程序属性和事件监听器,但JavaScript中还有很多事件。 我们将在下面介绍几个最常见的事件。
鼠标事件
鼠标事件是最常用的事件之一。 它们是指涉及鼠标上的单击按钮或悬停和移动鼠标指针的事件。 这些事件也对应于Touch设备上的等效操作。
事件 | 描述 |
---|---|
click | 当鼠标按下并释放元素时触发 |
dblclick | 点击两次元素时触发 |
mouseenter | 当指针进入元素时触发 |
mouseleave | 当指针离开元素时触发 |
mousemove | 每次指针在元素内移动时触发 |
click
是一个复合事件,它由组合的mousedown
和mouseup
事件组成,分别当鼠标按钮被按下或抬起时触发。
只要鼠标指针位于元素上,使用mouseenter
和mouseleave
一起重新创建悬停效果。
表单事件
表单事件是与表单相关的操作,如正在选择或未选中的input
元素以及正在提交的表单。
事件 | 描述 |
---|---|
submit | 提交表单时触发 |
focus | 当元素(如输入)获得焦点时触发 |
blur | 元素失去焦点时触发 |
选择某个元素时可实现焦点 ,例如,通过鼠标单击或通过TAB
键导航到该元素。
JavaScript通常用于提交表单并将值发送到后端语言。 使用JavaScript发送表单的优点是它不需要页面重新加载来提交表单,并且JavaScript可以用于验证所需的输入字段。
键盘事件
键盘事件用于处理键盘操作,例如按下按键,抬起按键并按住按键。
事件 | 描述 |
---|---|
keydown | 按下某个键时触发一次 |
keyup | 当钥匙被释放时发射一次 |
keypress | 按下键时持续闪光 |
尽管它们看起来很相似,但keydown
和keypress
事件不能访问所有完全相同的密钥。 虽然keydown
会确认每个按下的keypress
,但keypress
将省略不产生字符的keypress
,如SHIFT
, ALT
或DELETE
。
键盘事件具有访问各个键的特定属性。
如果将一个称为event
对象的参数传递给事件监听器,则可以访问有关发生的操作的更多信息。 与键盘对象有关的三个属性包括keyCode
, key
和code
。
例如,如果用户在他们的键盘上按下字母键,那么与该键有关的以下属性将会显示:
属性 | 描述 | 例 |
---|---|---|
keyCode | 一个关键的数字 | 65 |
key | 代表角色名称 | 一个 |
code | 代表被按下的物理键 | 科亚 |
为了展示如何通过JavaScript控制台收集这些信息,我们可以编写以下几行代码。
// Test the keyCode, key, and code propertiesdocument.addEventListener('keydown', event => { console.log('key: ' + event.keyCode); console.log('key: ' + event.key); console.log('code: ' + event.code);});
一旦我们按下控制台上的ENTER
,我们现在就可以按下键盘上的一个键,在这个例子中,我们将按下a
键。
keyCode: 65key: acode: KeyA
keyCode
属性是一个与已被按下的键有关的数字。 key
属性是可以更改的字符的名称 – 例如,使用SHIFT
按a
会导致A
的key
。 code
属性表示键盘上的物理键。
请注意, keyCode
正在被弃用,并且最好在新项目中使用code
。
要了解更多信息,您可以在Mozilla开发者网络上查看完整的事件列表 。
事件对象
Event
对象由所有事件可以访问的属性和方法组成。 除了通用的Event
对象外,每种类型的事件都有其自己的扩展,如KeyboardEvent
和MouseEvent
。
Event
对象作为参数传递给监听器函数。 它通常写作event
或e
。 我们可以访问keydown
事件的code
属性来复制PC游戏的键盘控件。
要试用它,请使用<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 listenerdocument.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
元素。
<!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>
在浏览器的开发者控制台中使用带有JavaScript的event.target
,我们可以将一个事件监听器放置在外部section
元素上,并获得最深嵌套的元素。
const section = document.querySelector('section');// Print the selected targetsection.addEventListener('click', event => { console.log(event.target);});
单击这些元素中的任何一个将使用event.target
将相关特定元素的输出返回到控制台。 这非常有用,因为它允许您只放置一个可用于访问许多嵌套元素的事件监听器。
通过Event
对象,我们可以设置与所有事件相关的响应,包括通用事件和更具体的扩展。
结论
事件是在网站上发生的操作,例如点击,悬停,提交表单,加载页面或按下键盘上的按键。 当我们能够让网站响应用户采取的行动时,JavaScript就变得真正的互动和动态。
在本教程中,我们了解了哪些事件,常见事件的示例,事件处理程序和事件监听器之间的区别,以及如何访问Event
对象。 利用这些知识,您将能够开始制作动态网站和应用程序。