了解JavaScript中的事件

事件是在浏览器中发生的操作,可以由用户或浏览器本身启动。在这个JavaScript aticle中,我们将讨论事件处理程序,事件监听器和事件对象。我们还将通过三种不同的方式编写代码来处理事件,以及一些最常见的事件。通过了解事件,您可以为最终用户提供更具互动性的网络体验。

介绍

了解DOM系列中,我们讨论了DOM树以及如何使用开发人员工具控制台 访问遍历添加和删​​除以及修改节点和元素。

尽管在这一点上,我们现在可以对DOM所做的任何更改进行修改,但从用户角度来看,它并不是非常有用,因为我们只手动触发更改。 通过了解事件,我们将了解如何将所有事情联系在一起以制作互动网站。

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

  • 该页面完成加载
  • 用户点击一个按钮
  • 用户悬停在下拉列表中
  • 用户提交表单
  • 用户按下键盘上的按键

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

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

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

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

事件处理程序是一个JavaScript函数,在事件触发时运行。

一个事件监听器将一个响应接口附加到一个元素上,该元素允许该特定元素等待并“监听”给定事件触发。

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

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

我们将通过三种方法来确保您熟悉事件触发的每种方式,然后讨论每种方法的优缺点。

内联事件处理程序属性

要开始了解事件处理程序,我们将首先考虑内联事件处理程序 让我们从一个非常基本的例子开始,它由一个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.I changed because of an inline event handler.

首先响应events.html渲染事件

内联事件处理程序是开始理解事件的直接方式,但它们通常不应超出测试和教育目的。

您可以比较内联事件处理程序以在HTML元素上嵌入CSS样式。 维护一个单独的类样式表比在每个元素上创建内联样式要实用得多,正如维护完全通过单独的脚本文件处理JavaScript而不是为每个元素添加处理程序一样。

事件处理程序属性

内联事件处理程序的下一步是事件处理程序属性 这与内联处理程序非常类似,只不过我们使用JavaScript设置元素的属性而不是HTML中的属性。

除了我们不再在标记中包含onclick="changeText()"之外,这里的设置将与此相同:

events.html
...
<body>

    <button>Click me</button>

    <p>I will change.</p>

</body>
...

我们的函数也会保持相似,除了现在我们需要访问JavaScript中的button元素。 我们可以简单地访问onclick就像访问styleid或任何其他元素属性一样,然后分配函数引用。

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代码遵循的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事件处理程序的最新成员是事件监听器。 事件监听器监视元素上的事件。 我们将使用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 每个事件监听者都会从单词中删除。 在下一节中,我们将看到更多其他类型事件的例子。

当您使用上面的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中还有很多事件。 我们将在下面介绍几个最常见的事件。

鼠标事件

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

事件 描述
click 当鼠标按下并释放元素时触发
dblclick 点击两次元素时触发
mouseenter 当指针进入元素时触发
mouseleave 当指针离开元素时触发
mousemove 每次指针在元素内移动时触发

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

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

表单事件

表单事件是与表单相关的操作,如正在选择或未选中的input元素以及正在提交的表单。

事件 描述
submit 提交表单时触发
focus 当元素(如输入)获得焦点时触发
blur 元素失去焦点时触发

选择某个元素时可实现焦点 ,例如,通过鼠标单击或通过TAB键导航到该元素。

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

键盘事件

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

事件 描述
keydown 按下某个键时触发一次
keyup 当钥匙被释放时发射一次
keypress 按下键时持续闪光

尽管它们看起来很相似,但keydownkeypress事件不能访问所有完全相同的密钥。 虽然keydown会确认每个按下的keypress ,但keypress将省略不产生字符的keypress ,如SHIFTALTDELETE

键盘事件具有访问各个键的特定属性。

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

例如,如果用户在他们的键盘上按下字母键,那么与该键有关的以下属性将会显示:

属性 描述
keyCode 一个关键的数字 65
key 代表角色名称 一个
code 代表被按下的物理键 科亚

为了展示如何通过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键。

keyCode: 65
key: a
code: KeyA

keyCode属性是一个与已被按下的键有关的数字。 key属性是可以更改的字符的名称 - 例如,使用SHIFTa会导致Akey code属性表示键盘上的物理键。

请注意, keyCode正在被弃用,并且最好在新项目中使用code

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

事件对象

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

Event对象作为参数传递给监听器函数。 它通常写作evente 我们可以访问keydown事件的code属性来复制PC游戏的键盘控件。

要试用它,请使用<p>标签创建一个基本的HTML文件并将其加载到浏览器中。

事件测试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元素。

事件测试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>

在浏览器的开发者控制台中使用带有JavaScript的event.target ,我们可以将一个事件监听器放置在外部section元素上,并获得最深嵌套的元素。

const section = document.querySelector('section');

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

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

第二个事件对象示例

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

结论

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

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