JavaScript总结【11】事件简介

本文详细介绍了JavaScript中的事件处理,包括常用浏览器事件、事件对象、冒泡与捕获机制、事件委托,以及键盘、鼠标、表单等事件的使用。重点讨论了事件冒泡、捕获的原理以及如何使用addEventListener和removeEventListener方法。同时,还探讨了阻止浏览器默认行为和事件传播的三个阶段。
摘要由CSDN通过智能技术生成

目录

  • JavaScript 事件简介
    • 常用浏览器事件
    • Event
      • addEventListener
      • removeEventListener
      • event对象
    • 冒泡和捕获
      • 冒泡
      • DOM事件传播的3个阶段、捕获
      • 事件委托
    • 浏览器默认行为
      • 阻止浏览器默认行为
      • 处理程序选项passive
      • event.defaultPrevented
    • UI事件
      • 鼠标事件
        • 常用鼠标事件:
        • 触发顺序
        • 鼠标按钮
        • 组合键:`shift`、`alt`、`ctrl`、`meta`
        • 坐标
        • 防止鼠标按下时选择
      • 指针事件
        • 常用指针事件
        • 指针事件的属性
        • 事件:ponitercancel
        • 指针捕获
      • 键盘事件
      • 滚动
    • 表单、控件
      • 表单命名与获取
      • 表单元素
      • 聚焦:focus/blur
      • 事件change,input,cut,copy,paste
      • 表单事件和方法提交
      • 表单事件和方法提交

JavaScript 事件简介

常用浏览器事件

鼠标事件:

  • click —— 当鼠标点击一个元素时(触摸屏设备会在点击时生成)。
  • dbclick——在短时间内双击同一元素后触发。如今已经很少使用了
  • contextmenu —— 当鼠标右键点击一个元素时。
  • mouseover / mouseout —— 当鼠标指针移入/离开一个元素时。
  • mousedown / mouseup —— 当在元素上按下/释放鼠标按钮时。
  • mousemove —— 当鼠标移动时。

键盘事件

  • keydownkeyup —— 当按下和松开一个按键时。

表单(form)元素事件

  • submit —— 当访问者提交了一个 <form> 时。
  • focus —— 当访问者聚焦于一个元素时,例如聚焦于一个 <input>

Document 事件

  • DOMContentLoaded —— 当 HTML 的加载和处理均完成,DOM 被完全构建完成时。

CSS 事件

  • transitionend —— 当一个 CSS 动画完成时

Event

addEventListener

  1. 语法:element.addEventListener(event, handler[, options]);

  2. 参数:

    • event:事件名
    • handler:处理程序
    • options:可选参数
      • once:如果为 true,那么会在被触发后自动删除监听器。
      • capture:事件处理的阶段,捕获于冒泡
      • false/true,它与 {capture: false/true} 相同。
      • passive:如果为 true,那么处理程序将不会调用 preventDefault()
    1. 这里的handler也可以是对象/类,只要它包含对象处理程序handleEvent,必须是这个命名。当 addEventListener 接收一个对象作为处理程序时,在事件发生时,它就会调用 obj.handleEvent(event) 来处理事件
<button id="elem">Click me</button>

<script>
 let obj = {
   handleEvent(event) {
     alert(event.type + " at " + event.currentTarget);
   }
 };

 elem.addEventListener('click', obj);
</script>

removeEventListener

  1. 语法:element.removeEventListener(event, handler[, options]);
  2. 注意:要移除处理程序,我们需要传入与分配的函数完全相同的函数,因此箭头函数定义的监听器将无法移除,因为地址不同

event对象

当事件发生时,浏览器会创建一个 event 对象,将详细信息放入其中,并将其作为参数传递给处理程序:

  • event.type——事件类型
  • event.currentTarget——处理事件的元素。这与 this 相同,除非处理程序是一个箭头函数,或者它的 this 被绑定到了其他东西上,之后我们就可以从 event.currentTarget 获取元素了
  • event.clientX / event.clientY——指针事件(pointer event)的指针的窗口相对坐标
  • 其他

冒泡和捕获

冒泡

  1. 冒泡(bubbling):目标元素→父元素)当一个事件发生在一个元素上,它会首先运行在该元素上的处理程序,然后运行其父元素上的处理程序,然后一直向上到其他祖先上的处理程序

  2. 冒泡中的event.target

    父元素上的处理程序始终可以获取事件实际发生位置的详细信息。引发事件的那个嵌套层级最深的元素被称为目标元素,可以通过event.target 访问。它与 this(也是event.currentTarget)之间是有区别的:

    • event.target —— 是引发事件的“目标”元素,它在冒泡过程中不会发生变化。
    • this —— 是“当前”元素,其中有一个当前正在运行的处理程序
  3. 停止冒泡:

    冒泡事件从目标元素开始向上冒泡。通常,它会一直上升到 <html>,然后再到 document 对象,有些事件甚至会到达 window,它们会调用路径上所有的处理程序。但是任意处理程序都可以决定事件已经被完全处理,并停止冒泡。用于停止冒泡的方法是 event.stopPropagation()

<body onclick="alert(`the bubbling doesn't reach here`)">
  <button onclick="event.stopPropagation()">Click me</button>
</body>

通常,没有真正的必要去阻止冒泡

DOM事件传播的3个阶段、捕获

  1. 捕获阶段(Capturing phase)—— 事件(从 Window)向下走近元素。

  2. 目标阶段(Target phase)—— 事件到达目标元素。

  3. 冒泡阶段(Bubbling phase)—— 事件从元素上开始冒泡

    表格中点击 <td> 的图片时DOM传播过程:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4DEHmJMa-1637770704979)(C:\Users\HeHao\AppData\Roaming\Typora\typora-user-images\image-20211119005232611.png)]

为了在捕获阶段捕获事件,我们需要将处理程序的 capture 选项设置为 trueelem.addEventListener(..., {capture: true})elem.addEventListener(..., true)

apture 选项有两个可能的值:

  • 如果为 false(默认值),则在冒泡阶段设置处理程序。
  • 如果为 true,则在捕获阶段设置处理程序。

注意可以给事件click添加两个相同的方法,那么就又可以冒泡又可以捕获了

事件委托

  1. 什么是事件委托

    JavaScript事件委托也叫事件代理,实际上就是通过冒泡/捕获机制将一个元素的响应事件委托给另外一个元素,支持位同一个DOM注册多个同类型事件

  2. 事件委托的优点:

    • 减少内存消耗,提高性能
    • 可以动态绑定事件

浏览器默认行为

阻止浏览器默认行为

  • 主流的方式是使用 event 对象。有一个 event.preventDefault() 方法
  • 如果处理程序是使用 on<event>(而不是 addEventListener)分配的,那返回 false 也同样有效
<a href="/" onclick="return false">Click here</a>
<a href="/" onclick="event.preventDefault()">here</a>

处理程序选项passive

  1. addEventListener 的可选项 passive: true 向浏览器发出信号,表明处理程序将不会调用 preventDefault()

  2. 为什么需要这样做?移动设备上会发生一些事件,例如 touchmove(当用户在屏幕上移动手指时),默认情况下会导致滚动,但是可以使用处理程序的 preventDefault() 来阻止滚动。因此,当浏览器检测到此类事件时,它必须首先处理所有处理程序,然后如果没有任何地方调用 preventDefault,则页面可以继续滚动。但这可能会导致 UI 中不必要的延迟和“抖动”。passive: true 选项告诉浏览器,处理程序不会取消滚动。然后浏览器立即滚动页面以提供最大程度的流畅体验,并通过某种方式处理事件。对于某些浏览器(Firefox,Chrome),默认情况下,touchstarttouchmove 事件的 passivetrue

event.defaultPrevented

如果默认行为被阻止,那么 event.defaultPrevented 属性为 true,否则为 false

UI事件

鼠标事件

常用鼠标事件:
  • click —— 当鼠标点击一个元素时(触摸屏设备会在点击时生成)。
  • dbclick——在短时间内双击同一元素后触发。如今已经很少使用了
  • contextmenu —— 当鼠标右键点击一个元素时。
  • mouseover / mouseout —— 当鼠标指针移入/离开一个元素时。over、out、enter、leave
  • mousedown / mouseup —— 当在元素上按下/释放鼠标按钮时。
  • mousemove —— 当鼠标移动时。
触发顺序

遵循 mousedownmouseupclick

鼠标按钮
鼠标按键状态event.button
左键 (主要按键)0
中键 (辅助按键)1
右键 (次要按键)2
X1 键 (后退按键)3
X2 键 (前进按键)4
组合键:shiftaltctrlmeta
  • shiftKey:Shift

  • altKey:Alt(或对于 Mac 是 Opt)

  • ctrlKey:Ctrl

  • metaKey:对于 Mac 是 Cmd

<button id="button">Alt+Shift+Click on me!</button>

<script>
  button.onclick = function(event) {
    if (event.altKey && event.shiftKey) {
      alert('Hooray!');
    }
  };
</script>
坐标

所有的鼠标事件都提供了两种形式的坐标:

  • 相对于窗口的坐标:clientXclientY

  • 相对于文档的坐标:pageXpageY

防止鼠标按下时选择
  • 双击鼠标会有副作用,在某些界面中可能会出现干扰:它会选择文本。在这种情况下,最合理的方式是防止浏览器对 mousedown 进行操作。

  • **防止复制:**如果我们想禁用选择以保护我们页面的内容不被复制粘贴,那么我们可以使用另一个事件:oncopy

<div oncopy="alert('Copying forbidden!');return false">
  Dear user,
  The copying is forbidden for you.
  If you know JS or HTML, then you can get everything from the page source though.
</div>

指针事件

常用指针事件
指针事件类似的鼠标事件
pointerdownmousedown
pointerupmouseup
pointermovemousemove
pointerovermouseover
pointeroutmouseout
pointerentermouseenter
pointerleavemouseleave
pointercancel-
gotpointercapture-
lostpointercapture-
指针事件的属性

指针事件具备和鼠标事件完全相同的属性,包括 clientX/Ytarget 等,以及一些其他属性:

  • pointerId —— 触发当前事件的指针唯一标识符

    浏览器生成的。使我们能够处理多指针的情况,例如带有触控笔和多点触控功能的触摸屏

  • pointerType —— 指针的设备类型。必须为字符串,可以是:“mouse”、“pen” 或 “touch”。

    我们可以使用这个属性来针对不同类型的指针输入做出不同响应。

  • isPrimary —— 当指针为首要指针(多点触控时按下的第一根手指)时为 true

有些指针设备会测量接触面积和点按压力(例如一根手指压在触屏上),对于这种情况可以使用以下属性:

  • width —— 指针(例如手指)接触设备的区域的宽度。对于不支持的设备(如鼠标),这个值总是 1
  • height —— 指针(例如手指)接触设备的区域的长度。对于不支持的设备,这个值总是 1
  • pressure —— 触摸压力,是一个介于 0 到 1 之间的浮点数。对于不支持压力检测的设备,这个值总是 0.5(按下时)或 0
  • tangentialPressure —— 归一化后的切向压力(tangential pressure)。
  • tiltX, tiltY, twist —— 针对触摸笔的几个属性,用于描述笔和屏幕表面的相对位置

大多数设备都不支持这些属性,因此它们很少被使用。如果你需要使用它们, 可以翻阅规范文档

事件:ponitercancel

pointercancel 事件将会在一个正处于活跃状态的指针交互由于某些原因被中断时触发。也就是在这个事件之后,该指针就不会继续触发更多事件了。自定义拖放事件必须阻止浏览器默认指针事件!可以通过JSelem.ondragstart = () => false或者CSS的elem { touch-action: none }

导致指针中断的可能原因如下:

  • 指针设备硬件在物理层面上被禁用。
  • 设备方向旋转(例如给平板转了个方向)。
  • 浏览器打算自行处理这一交互,比如将其看作是一个专门的鼠标手势或缩放操作等。
指针捕获

elem.setPointerCapture(pointerId) —— 将给定的 pointerId 绑定到 elem。在调用之后,所有具有相同 pointerId 的指针事件都将 elem 作为目标(就像事件发生在 elem 上一样),无论这些 elem 在文档中的实际位置是什么。

绑定会在以下情况下被移除:

  • pointeruppointercancel 事件出现时,绑定会被自动地移除。
  • elem 被从文档中移除后,绑定会被自动地移除。
  • elem.releasePointerCapture(pointerId) 被调用,绑定会被移除

键盘事件

  • keydown
  • keyup

滚动

  1. scroll 事件允许对页面或元素滚动作出反应。我们可以在这里做一些有用的事情。

  2. 防止滚动:**不能通过在 onscroll 监听器中使用 event.preventDefault() 来阻止滚动,因为它会在滚动发生之后才触发。但可以处理导致滚动的事件防止滚动**,例如在 pageUp 和 pageDown 的 keydown 事件上,使用 event.preventDefault() 来阻止滚动

  3. 启动滚动:方法很多,使用 CSS 的 overflow 属性更加可靠

表单、控件

表单命名与获取

  1. 文档中的表单是特殊集合 document.forms 的成员。这就是所谓的“命名的集合”,既是被命名了的,也是有序的。我们既可以使用名字,也可以使用在文档中的编号来获取表单。
document.forms.my - name="my" 的表单
document.forms[0] - 文档中的第一个表单
  1. 可能会有多个名字相同的元素,这种情况经常在处理单选按钮中出现。在这种情况下,form.elements[name] 将会是一个集合,例如:
<form>
  <input type="radio" name="age" value="10">
  <input type="radio" name="age" value="20">
</form>

<script>
let form = document.forms[0];

let ageElems = form.elements.age;

alert(ageElems[0]); // [object HTMLInputElement]
</script>
  1. 对于任何元素,其对应的表单都可以通过 element.form 访问到。因此,表单引用了所有元素,元素也引用了表单。

  2. 反向引用:对于任何元素,其对应的表单都可以通过 element.form 访问到。因此,表单引用了所有元素,元素也引用了表单。

表单元素

  1. input和textarea

    我们可以通过 input.value(字符串)或 input.checked(布尔值)来访问复选框(checkbox)中的它们的 value

  2. select和option:

    一个 <select> 元素有 3 个重要的属性:

    • select.options —— <option> 的子元素的集合,
    • select.value —— 当前所选择的 <option>value
    • select.selectedIndex —— 当前所选择的 <option> 的编号。

    它们提供了三种为 <select> 设置 value 的不同方式:

    • 找到对应的 <option> 元素,并将 option.selected 设置为 true
    • select.value 设置为对应的 value
    • select.selectedIndex 设置为对应 <option> 的编号。
<select id="select">
  <option value="apple">Apple</option>
  <option value="pear">Pear</option>
  <option value="banana">Banana</option>
</select>

<script>
  // 所有这三行做的是同一件事
  select.options[2].selected = true;
  select.selectedIndex = 2;
  select.value = 'banana';
</script>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZTjyOp1O-1637770704982)(C:\Users\HeHao\AppData\Roaming\Typora\typora-user-images\image-20211124234827771.png)]

聚焦:focus/blur

  1. 事件

    • elem.onfocus = func

    • elem.onblur = func

  2. 方法

    • elem.focus() 使成为焦点
    • elem.blur() 使失去焦点
  3. 允许在任何元素上聚焦:tabindex

    默认情况下,很多元素不支持聚焦。任何浏览器中focus/blur 都支持这些用户可以交互的元素如<button><input><select><a> 等。但一些诸如<div><span>等元素却不能,但是我们可以使用HTML-特性(attribute)tabindex 可以改变这种情况。任何具有 tabindex 特性的元素,都会变成可聚焦的。该特性的 value 是当使用 Tab(或类似的东西)在元素之间进行切换时,元素的顺序号。tabindex的值决定Tab键跳转的顺序

  4. 委托

    focusblur 事件不会向上冒泡。目前又两个解决方案:

    • 捕获
    • 使用 focusinfocusout 事件 —— 与 focus/blur 事件完全一样,只是它们会冒泡。但必须使用elem.addEventListener 来分配它们,而不是 on<event>

    事件change,input,cut,copy,paste

    1. change:当元素更改完成时,将触发 change 事件。对于文本输入框,当其失去焦点时,就会触发 change 事件。对于其它元素:selectinput type=checkbox/radio,会在选项更改后立即触发 change 事件。
    2. input:每当用户对输入值进行修改后,就会触发 input 事件,无法使用event.preventDefault()阻止事件发生
    3. cut,copy,paste:可以使用 event.preventDefault() 来中止行为。event.clipboardData 属性可以用于读/写剪贴板。

表单事件和方法提交

提交表单时,会触发 submit 事件,它通常用于在将表单发送到服务器之前对表单进行校验,或者中止提交,并使用 JavaScript 来处理表单

  1. submit事件

    提交表单主要有两种方式:

    • 点击 <input type="submit"><input type="image">
    • input 字段中按下 Enter 键。

    这两个行为都会触发表单的 submit 事件。处理程序可以检查数据,如果有错误,就显示出来,并调用 event.preventDefault(),这样表单就不会被发送到服务器了。

  2. submit方法

    如果要手动将表单提交到服务器,我们可以调用 form.submit()。这样就不会产生 submit 事件。

属性可以用于读/写剪贴板。

表单事件和方法提交

提交表单时,会触发 submit 事件,它通常用于在将表单发送到服务器之前对表单进行校验,或者中止提交,并使用 JavaScript 来处理表单

  1. submit事件

    提交表单主要有两种方式:

    • 点击 <input type="submit"><input type="image">
    • input 字段中按下 Enter 键。

    这两个行为都会触发表单的 submit 事件。处理程序可以检查数据,如果有错误,就显示出来,并调用 event.preventDefault(),这样表单就不会被发送到服务器了。

  2. submit方法

    如果要手动将表单提交到服务器,我们可以调用 form.submit()。这样就不会产生 submit 事件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值