分类
文章

理解javascript中的事件

介绍

在” 了解DOM”系列中,我们讨论了DOM树以及如何使用Developer Tools Console开发访问遍历添加和删除以及修改节点和元素。

尽管此时我们几乎可以对DOM进行任何更改,但是从用户角度看,它并不是很有帮助,因为我们只有手动触发的更改。通过了解事件,我们将了解如何将所有内容结合在一起以创建交互式网站。

Events是在浏览器中发生的操作,可由用户或浏览器本身启动。以下是一些可能在网站上发生的常见事件的示例:

  • 页面加载完成
  • 用户单击一个按钮
  • 用户将鼠标悬停在下拉菜单上
  • 用户提交表格
  • 用户按下键盘上的一个键

通过对在事件上执行的JavaScript响应进行编码,开发人员可以向用户显示消息,验证数据,对按钮单击做出反应以及许多其他操作。

在本文中,我们将介绍事件处理程序,事件侦听器和事件对象。我们还将介绍三种不同的编写代码来处理事件的方式,以及一些最常见的事件。通过了解事件,您将能够为最终用户提供更具交互性的Web体验。

事件处理程序和事件侦听器

当用户单击按钮或按下键时,将触发一个事件。这些分别称为单击事件或按键事件。

event handler是在事件触发时运行的JavaScript函数。

event listener将响应接口附加到元素,该接口允许该特定元素等待并”监听”给定事件的触发。

有三种将事件分配给元素的方法:

  • 内联事件处理程序
  • 事件处理程序属性
  • 事件监听器

我们将介绍所有三种方法,以确保您熟悉触发事件的每种方式,然后讨论每种方法的利弊。

内联事件处理程序属性

为了开始了解事件处理程序,我们首先考虑inline event handler 。让我们从一个非常基本的示例开始,该示例由button元素和p元素组成。我们希望用户单击button以更改p的文本内容。

让我们从一个带有按钮的HTML页面开始。我们将引用一个JavaScript文件,稍后向其中添加代码。

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>

直接在button ,我们将添加一个名为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 ,您会看到一个如下所示的页面:

第一次呈现events.html

但是,当您或另一个用户单击该按钮时, p标签的文本将从” Try to change me. I changed because of an inline event handler. :

对events.html渲染上的事件的首次响应

内联事件处理程序是开始了解事件的直接方法,但通常不应将其用于测试和教育目的。

您可以将内联事件处理程序与HTML元素上的内联CSS样式进行比较。维护类的单独样式表比在每个元素上创建内联样式要实用得多,就像维护完全通过单独的脚本文件处理的JavaScript比向每个元素添加处理程序更可行。

事件处理程序属性

内联事件处理程序的下一步是event handler property 。这与内联处理程序非常相似,除了我们在JavaScript中设置元素的属性而不是HTML中的属性。

除了我们不再在标记中包括onclick="changeText()"之外,此处的设置相同。

events.html
...
<body>
    <button>Click me</button>
    <p>I will change.</p>
</body>
...

我们的功能也将保持相似,除了现在我们需要访问JavaScript中的button元素。我们可以像访问styleid或任何其他元素属性一样简单地访问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;

Note:事件处理程序不遵循大多数JavaScript代码所遵循的camelCase约定。注意,代码是onclick ,不是onClick

首次加载页面时,浏览器将显示以下内容:

使用事件处理程序的events.html的初始加载

现在,当您单击按钮时,它将具有与以前相似的效果:

使用events.html的事件处理程序进行响应

请注意,在将函数引用传递给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()代码是添加到属性中的最后一个。

通过events.html的事件处理程序进行最终响应

了解内联事件处理程序和事件处理程序属性后,让我们继续进行事件侦听器。

事件监听器

JavaScript事件处理程序的最新功能是事件侦听器。event listener监视元素上的事件。我们将使用addEventListener()方法侦听事件,而不是将事件直接分配给元素上的属性。

addEventListener()具有两个必需参数-要监听的事件和监听器回调函数。

我们的事件侦听器的HTML与前面的示例相同。

events.html
...
    <button>Click me</button>
    <p>I will change.</p>
...

我们仍将使用与changeText()相同的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);

请注意,在前两种方法中,click事件称为onclick ,而在事件侦听器中则称为click 。每一个事件侦听器滴on的字。在下一节中,我们将查看其他类型事件的更多示例。

当使用上面的JavaScript代码重新加载页面时,您将收到以下输出:

events.html的事件侦听器响应

乍一看,事件侦听器似乎与事件处理程序属性非常相似,但是它们有一些优点。我们可以在同一元素上设置多个事件侦听器,如下面的示例所示。

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);

在此示例中,两个事件都将触发,一旦单击警报,将为用户提供警报和修改后的文本。

通常,将使用匿名函数代替事件侦听器上的函数引用。匿名函数是未命名的函数。

// 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);

此外,您可以在documentwindow对象上使用addEventListener()

当前,事件侦听器是处理JavaScript中事件的最常见和首选方式。

共同事件

我们已经了解了使用click事件的内联事件处理程序,事件处理程序属性和事件侦听器,但是JavaScript中还有更多事件。我们将在下面介绍一些最常见的事件。

鼠标事件

鼠标事件是最常用的事件之一。它们是指涉及单击鼠标按钮或悬停并移动鼠标指针的事件。这些事件还对应于触摸设备上的等效操作。

Event Description
click Fires when the mouse is pressed and released on an element
dblclick Fires when an element is clicked twice
mouseenter Fires when a pointer enters an element
mouseleave Fires when a pointer leaves an element
mousemove Fires every time a pointer moves inside an element

click是复合事件,由组合的mousedownmouseup事件组成,分别在按下或抬起鼠标按钮时触发。

串联使用mouseentermouseleave重新创建一个悬停效果,只要鼠标指针位于元素上即可。

表单活动

表单事件是与表单有关的动作,例如选择或取消选择input元素以及提交表单。

Event Description
submit Fires when a form is submitted
focus Fires when an element (such as an input) receives focus
blur Fires when an element loses focus

当选择一个元素时,例如,通过单击鼠标或通过TAB键导航到该元素,即可实现Focus

JavaScript通常用于提交表单并将值发送到后端语言。使用JavaScript发送表单的优点是不需要重新加载页面即可提交表单,并且JavaScript可用于验证所需的输入字段。

键盘事件

键盘事件用于处理键盘操作,例如按下键,抬起键和按住键。

Event Description
keydown Fires once when a key is pressed
keyup Fires once when a key is released
keypress Fires continuously while a key is pressed

尽管它们看上去很相似,但是keydownkeypress事件无法访问所有完全相同的键。虽然keydown会确认每个已按下的键,但keypress会忽略不产生任何字符的SHIFT ,例如SHIFTALTDELETE

键盘事件具有用于访问单个键的特定属性。

如果将一个称为event对象的参数传递给事件侦听器,我们可以访问有关发生的操作的更多信息。与键盘对象有关的三个属性包括keyCodekeycode

例如,如果用户按下字母a其键盘上键,关于该密钥的以下性质将表面:

Property Description Example
keyCode A number pertaining to the key 65
key Represents the character name a
code Represents the physical key being pressed KeyA

为了显示如何通过JavaScript控制台收集信息,我们可以编写以下代码行。

// Test the keyCode, key, and code properties
document.addEventListener('keydown', event => {
    console.log('key: ' + event.keyCode);
    console.log('key: ' + event.key);
    console.log('code: ' + event.code);
});

一旦我们按ENTER在控制台上,我们现在可以按键盘上的按键,在这个例子中,我们会按a

OutputkeyCode: 65
key: a
code: KeyA

keyCode属性是一个与已按下的键有关的数字。key属性是字符的名称,可以更改-例如,用SHIFT按下a将产生key A code属性表示键盘上的物理键。

请注意, keyCode正在弃用的过程中,最好在新项目中使用code

要了解更多信息,可以在Mozilla开发人员网络上查看事件完整列表

事件对象

Event对象由所有事件都可以访问的属性和方法组成。除了通用的Event对象之外,每种类型的事件都有自己的扩展名,例如KeyboardEventMouseEvent

Event对象通过侦听器函数作为参数传递。通常写为evente 。我们可以访问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;
    }
});

当您按asdw键之一时,您将看到类似于以下内容的输出:

第一个事件对象示例

从这里,您可以继续开发浏览器将如何响应以及用户按下这些键的响应,并可以创建一个更具动态性的网站。

接下来,我们将介绍最常用的事件属性之一: 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和JavaScript,我们可以在外部section元素上放置一个事件侦听器,并获得嵌套最深的元素。

const section = document.querySelector('section');
// Print the selected target
section.addEventListener('click', event => {
    console.log(event.target);
});

单击这些元素中的任何一个,将使用event.target将相关特定元素的输出返回到控制台。这非常有用,因为它仅允许您放置一个事件侦听器,该事件侦听器可用于访问许多嵌套元素。

第二事件对象示例

使用Event对象,我们可以设置与所有事件相关的响应,包括通用事件和更具体的扩展。

结论

事件是在网站上发生的操作,例如单击,悬停,提交表单,加载页面或按键盘上的键。当我们能够使网站响应用户所采取的行动时,JavaScript就会变得真正互动和动态。

在本教程中,我们了解了什么是事件,常见事件的示例,事件处理程序和事件侦听器之间的区别以及如何访问Event对象。使用这些知识,您将可以开始制作动态网站和应用程序。

发表评论

电子邮件地址不会被公开。 必填项已用*标注