• 半小时带你全面理解 JavaScript 事件机制


    简介

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

    • 页面完成加载

    • 用户点击按钮

    • 用户将鼠标悬停在下拉菜单上

    • 用户提交表单

    • 用户按下键盘上的键

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

    本文将介绍事件处理程序、事件侦听器和事件对象。还将介绍三种不同的方式来处理事件,以及一些最常见的事件。了解事件可以帮助开发人员为用户提供更具交互性的web体验。

    事件处理程序(Event Handlers)和事件侦听器(Event Listeners)

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

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

    事件侦听器附加响应式接口到元素,允许特定元素等待并“侦听”给定事件的触发。

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

    • 内联事件处理程序

    • 事件处理程序属性

    • 事件监听器

    下面我们将一一介绍这三种方法的优缺点。

    内联事件处理程序属性

    要学习事件处理程序,首先要了解内联事件处理程序。让我们从一个由button元素和p元素组成的基本示例开始:用户单击按钮时更改p的文本内容。

    events.html

    1. <!DOCTYPE html>
    2. <html lang="en-US">
    3. <head>
    4.  <title>Events</title>
    5. </head>
    6. <body>
    7.   <!-- Add button -->
    8.   <button>Click me</button>
    9.   <p>Try to change me.</p>
    10. </body>
    11. <!-- Reference JavaScript file -->
    12. <script src="js/events.js"></script>
    13. </html>

    直接在按钮上添加onclick属性。属性值是我们创建的名为changeText()的函数。

    events.html

    1. <!DOCTYPE html>
    2. <html lang="en-US">
    3. <head>
    4.  <title>Events</title>
    5. </head>
    6. <body>
    7.  <button onclick="changeText()">Click me</button>
    8.  <p>Try to change me.</p>
    9. </body>
    10. <script src="js/events.js"></script>
    11. </html>

    创建events.js文件,并放在此处的js/目录中。再创建changeText()函数,用于修改p元素的textContent

    js/events.js

    1. // Function to modify the text content of the paragraph
    2. const changeText = () => {
    3.  const p = document.querySelector('p');
    4.  p.textContent = "I changed because of an inline event handler.";
    5. }

    首次加载events.html时,你可以看到如下所示的页面:

    648289d8daee42a0b690f5e1f1d64911.jpg

     

    单击按钮,p元素的文本将“Try to change me”更改为“I changed because of an inline event handler.”:

    c89f50aee27748d092c333590fcdbd49.jpg

     

    内联事件处理程序有助于直接理解事件,但通常用于测试和教学演示,正式项目中不推荐使用。

    事件处理程序属性

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

    此处的设置相同,只是不再在标记中包含onclick="changeText()"

    events.html

    1. ...
    2. <body>
    3.  <button>Click me</button>
    4.  <p>I will change.</p>
    5. </body>
    6. ...

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

    js/events.js

    1. Function to modify the text content of the paragraph
    2. const changeText = () => {
    3.  const p = document.querySelector('p');
    4.  p.textContent = "I changed because of an event handler property.";
    5. }
    6. // Add event handler as a property of the button element
    7. const button = document.querySelector('button');
    8. button.onclick = changeText;

    注意:事件处理程序不遵循大多数JavaScript代码所遵循的驼峰式命名规则。注意是onclick,而不是onClick

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

    0ca1f96ea5ad475d91b666ec322de519.jpg

     

    现在单击按钮,将实现与之前类似的效果:

    bfabfa95f44d44fc995d2861be0f9520.jpg

     

    注意,在将函数引用传递给onclick属性时,不包括括号,因为此时并没有调用函数,只是传递了对它的引用。

    事件处理程序属性比内联处理程序更易于维护,但仍然受制于一些相同的障碍。例如,尝试设置多个单独的onclick属性将导致除最后一个之外的所有属性都被覆盖,如下所示。

    js/events.js

    1. const p = document.querySelector('p');
    2. const button = document.querySelector('button');
    3. const changeText = () => {
    4.  p.textContent = "Will I change?";
    5. }
    6. const alertText = () => {
    7.  alert('Will I alert?');
    8. }
    9. // Events can be overwritten
    10. button.onclick = changeText;
    11. button.onclick = alertText;

    在上面的示例中,单击button只会弹出提示框,不会更改p元素的文本,因为alert()是最后一个添加到onclick属性中的。

    bf0c716ca04a44ca97a8af2c1843df55.jpg

     

    事件监听器

    事件侦听器监视元素上的事件。我们将使用addEventListener()方法来侦听事件,而并不是将事件直接分配给元素上的属性。

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

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

    events.html

    1. ...
    2.  <button>Click me</button>
    3.  <p>I will change.</p>
    4. ...

    我们仍将使用与之前相同的changeText()函数。将addEventListener()方法附加到按钮上。

    js/events.js

    1. // Function to modify the text content of the paragraph
    2. const changeText = () => {
    3.  const p = document.querySelector('p');
    4.  p.textContent = "I changed because of an event listener.";
    5. }
    6. // Listen for click event
    7. const button = document.querySelector('button');
    8. button.addEventListener('click', changeText);

    注意,在前两种方法中,点击事件被称为onclick,但在事件侦听器中,被称为click。每个事件侦听器都会剔除单词中的on

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

    3096f2031e904e29af06beaf3759deb9.jpg

     

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

    js/events.js

    1. const p = document.querySelector('p');
    2. const button = document.querySelector('button');
    3. const changeText = () => {
    4.  p.textContent = "Will I change?";
    5. }
    6. const alertText = () => {
    7.  alert('Will I alert?');
    8. }
    9. // Multiple listeners can be added to the same event and element
    10. button.addEventListener('click', changeText);
    11. button.addEventListener('click', alertText);

    上面的两个事件都将触发:首先弹出提示框,一旦点击关闭提示框后便修改p元素的内容。

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

    1. // An anonymous function on an event listener
    2. button.addEventListener('click'() => {
    3.  p.textContent = "Will I change?";
    4. });

    我们也可以使用removeEventListener()函数从元素中删除一个或所有事件。

    1. // Remove alert function from button element
    2. button.removeEventListener('click', alertText);

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

    事件侦听器是目前在JavaScript中处理事件最常用的首选方式。

    常用事件

    除了内联事件处理程序、事件处理程序属性和事件侦听器,JavaScript中还有更多事件。下面我们将讨论一些最常见的事件。

    鼠标事件

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

    事件描述
    click在元素上按下和释放鼠标时触发
    dblclick双击元素时触发
    mouseenter当鼠标进入元素时触发
    mouseleave当鼠标离开元素时触发
    mousemove每当鼠标在元素内移动时触发

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

    使用mouseentermouseleave之后将重新创建悬停效果,只要鼠标指针位于元素上,效果就会持续。

    表单事件

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

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

    当元素被选中时,例如,通过鼠标单击或TAB键导航到元素时,将获得焦点。

    使用JavaScript发送表单的优点是提交表单时不需要重新加载页面,并且可以使用JavaScript来验证所需的输入字段。

    键盘事件

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

    事件描述
    keydown按下键时触发一次
    keyup释放键时触发一次
    keypress按下键时连续触发

    虽然键盘事件看起来很相似,但keydownkeypress事件访问的键并不所有完全相同。keydown将确认按下的每个键,而keypress将忽略不产生字符的键,例如SHIFTALT以及DELETE

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

    假如将一个参数,例如event对象,传递给事件侦听器,那么我们可以访问有关所发生操作的更多信息。与键盘对象相关的两个属性包括keycode

    例如,如果用户按下键盘上的字母a键,则与该键相关的以下属性将浮出水面:

    属性描述示例
    key表示字符名称a
    code表示被按下的物理键KeyA

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

    1. // Test the key and code properties
    2. document.addEventListener('keydown'event => {
    3.  console.log('key: ' + event.key);
    4.  console.log('code: ' + event.code);
    5. });

    一旦我们在控制台按下ENTER键,就可以在键盘上按键,在本例中,按的是a

    1. Output
    2. key: a
    3. code: KeyA

    key属性是字符的名称,可以改变——例如,按下SHIFTa会变成A。而code属性表示的是键盘上的物理键。

    事件对象

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

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

    创建一个带有<p>标记的基本HTML文件并将其加载到浏览器中。

    event-test-p.html

    1. <!DOCTYPE html>
    2. <html lang="en-US">
    3. <head>
    4.     <title>Events</title>
    5. </head>
    6. <body>
    7.   <p></p>
    8. </body>
    9. </html>

    然后,在浏览器的开发者控制台中输入以下JavaScript代码。

    1. // Pass an event through to a listener
    2. document.addEventListener('keydown'event => {
    3.  var element = document.querySelector('p');
    4.  // Set variables for keydown codes
    5.  var a = 'KeyA';
    6.  var s = 'KeyS';
    7.  var d = 'KeyD';
    8.  var w = 'KeyW';
    9.  // Set a direction for each code
    10.  switch (event.code) {
    11.   case a:
    12.    element.textContent = 'Left';
    13.    break;
    14.   case s:
    15.    element.textContent = 'Down';
    16.    break;
    17.   case d:
    18.    element.textContent = 'Right';
    19.    break;
    20.   case w:
    21.    element.textContent = 'Up';
    22.    break;
    23.  }
    24. });

    当你按下其中一个键(asdw)时,将看到类似以下内容的输出:

    75d58724a275494a825e290ef2faf78d.jpg

     

    接下来,你可以继续开发浏览器如何响应以及用户按下这些键的方式,创建一个更加动态的网站。

    继续介绍最常用的事件属性之一:target属性。在下面的示例中,在section中有三个div元素。

    event-test-div.html

    1. <!DOCTYPE html>
    2. <html lang="en-US">
    3. <head>
    4.     <title>Events</title>
    5. </head>
    6. <body>
    7.   <section>
    8.    <div id="one">One</div>
    9.    <div id="two">Two</div>
    10.    <div id="three">Three</div>
    11.   </section>
    12. </body>
    13. </html>

    通过在浏览器的开发者控制台中使用event.target,我们可以将事件侦听器放置在外部section元素上,并获取嵌套最深的元素。

    1. const section = document.querySelector('section');
    2. // Print the selected target
    3. section.addEventListener('click'event => {
    4.  console.log(event.target);
    5. });

    单击其中任何一个元素都会返回相关特定元素的输出到控制台。这非常有用,因为你只需要放置一个事件侦听器,就可以访问许多嵌套元素。

    680d96b1c73e40438662dfe81929817b.jpg

     

    总结

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

    本文结束!感谢大家的阅读!

     

     

     

  • 相关阅读:
    selenium4.0以上元素被定位
    HJ46 截取字符串
    老问题了:idea中使用maven archetype新建项目时卡住
    【计算机视觉 | 图像分割】arxiv 计算机视觉关于图像分割的学术速递(8 月 28 日论文合集)
    基于C#通过PLCSIM ADV仿真软件实现与西门子1500PLC的S7通信方法演示
    小程序用户体系全攻略:openid和code的神秘连接,快速实现登录功能!告别繁琐的账号密码验证!
    当下最强的 AI art 生成模型 Stable Diffusion 最全面介绍
    文章分类列表进行查询(实体类日期格式设置)
    民安智库(第三方满意度调研公司)如何做物业满意度调查
    抖音短视频实操:抖音热门视频的分类特点,如何选择视频内容(上)
  • 原文地址:https://blog.csdn.net/weixin_43044226/article/details/125583259