JavaScript入门⑧-事件总结大全


JavaScript入门系列目录

  • JavaScript入门⑨-异步编程●异世界之旅
  • JavaScript入门⑩-ES6归纳总结

01、事件基础

1.1、事件简介

事件(Event)是JavaScript的心脏,触发各种交互,让网页动起来。事件是浏览器网页可以监测到的行为,如页面加载、鼠标点击、键盘按键等。在这些事件中可以自定义事件处理程序,用于实现各种业务需求。

事件对象的继承关系:

常见的事件类型、事件如下:

?鼠标事件(event)
click(event) 点击触发,通常是鼠标左键在一个元素上被按下并放开时
dblclick 双击触发事件
contextmenu 鼠标右键点击触发
mousedownmouseup 鼠标按下、弹起时触发
mousemove 鼠标在元素上移动时触发
onmouseovermouseout 鼠标移入、移出元素区域时触发
mouseenter、mouseleave 鼠标移入、移出元素区域时触发,与上面不同的是不会冒泡
dragstart、dragend 拖放事件(drag/dr?ɡ/拖)
?键盘事件(event)
keydown、keyup 键盘按键按下、松开时触发
?表单事件(event)
blur(event)、focusout() 元素失去焦点,blur不会冒泡 (blue /bl??r/ 模糊 /不乐/)
focus、focusin 元素获取焦点时触发,focus不会冒泡
from.submit 提交表单form时触发,可用于表单校验
change 值发生变化时触发,文本框是在值变化且失去焦点是才触发
input 输入值改变时触发,event.preventDefault()无法阻止,因为已经改变了
?Document 事件(event) 文档生命周期:DOMContentLoaded ?? load ?? beforeunload ?? unload
doc.DOMContentLoaded 已加载 HTML并构建好DOM树,外部资源(image、css)可能尚未加载完成
- 如果遇到

1.3、事件对象event

每一个事件处理程序都有一个event对象,内置了事件的详细信息。最基础的Event如下,还有很多继承事件对象。

?Event属性
type 事件的类型
target 指向事件触发的目标元素,可能为子元素,冒泡中不会改变。originalTarget为非标准(Mozilla)
currentTarget = this 指向事件绑定的元素,当前正在处理事假的元素,同 this
isTrusted 触发方式,true=用户,false=脚本触发,(Trusted/?tr?st?d/ 可信的)
bubbles 判断事件是否冒泡,bool。( Bubble/?b?b(?)l/ 冒泡)
cancelBubble?? 是否取消冒泡,可设置true阻止冒泡,stopPropagation()的别名
composed 表示事件是否可以穿过 Shadow DOM 和常规 DOM 之间的隔阂进行冒泡,bool
event.clientX / clientY 鼠标事件触发的x、y坐标
?Event 方法
stopPropagation() 停止向上冒泡(propagation /?pr?p??ɡe??n/ 传播),不影响当前元素的其他注册事件
stopImmediatePropagation() 取消后面的同类型事件的执行,包括冒泡,(Immediate /??mi?di?t/ 立刻)
preventDefault() 取消默认事件行为,如checkbox、,不影响冒泡。defaultPrevented 判断是否取消了

使用event.preventDefault() 可以移除浏览器的默认事件行为,也可以用return false

QQ-1 QQ-2 QQ-3

1.4、事件流:冒泡和捕获

事件的触发大都是某一个HTML元素,但这一个元素触发事件时,该事件会在该元素与根节点之间进行顺序传播,路过的元素都会接收到该事件,这个过程称为“事件流”,简单来说就是接收事件的顺序,如下三个阶段。

① 捕获阶段(Capturing phase):(phase /fe?z/ 阶段)

事件(从 Window)逐级向下传播,直到具体的目标元素。捕获阶段实际上很少使用,默认情况下也不会触发,addEventListener 注册事件时通过参数对象options.capture = true设置在捕获阶段触发事件。ediv.addEventListener("click", fevent2, true /* { capture: true } */);

② 目标阶段(Target phase):事件到达目标元素。

?目标元素 event.target:直接触发事件的、最近的那个元素,也是嵌套最深的那个元素。

③ 冒泡阶段(Bubbling phase):一般常用的是冒泡阶段,这更符合逻辑。

事件从目标元素上开始冒泡,逐级向上春波,直到根节点。几乎所有事件都会冒泡,除了个别的,如blurfocus没有冒泡。

事件流的两种传播方式其实是IE和Netscape两个公司的不同处理机制导致的。

?? 停止冒泡stopPropagation()stopImmediatePropagation()

  • 注意的区别stopPropagation()只是停止向上冒泡;stopImmediatePropagation()会额外取消当前元素同类型的后续事件。
  • 非必要不主动关闭冒泡,谨慎使用,可能会影响其他功能。

1.5、事件委托

事件委托只是事件的一种使用方式而已,基于事件冒泡在,上级节点统一处理从而简化事件的绑定。比如有一堆导航按钮,不需要每个都添加事件,把点击事件委托给其父级元素统一处理。

  • 优点:简化代码逻辑,便于修改维护。
  • 缺点:事件必须冒泡,如果被阻止了,就嗝屁了;可以忽略的冒泡性能损失。

表格排序示例(委托给表格统一处理):codePen地址

//需求:点击表格标题,对数据进行排序
const table = document.querySelector("#grid");
table.onclick = function (e) {
  //点击标题单元格,并且有自定义排序属性
  if (e.target.tagName != "TH" || !e.target.hasAttribute("data-sort")) return;
  let th = e.target;
  sortTable(th.cellIndex, th.dataset.sort);
};
function sortTable(colIndex, type) {
  let trs = Array.from(document.querySelectorAll("#grid tbody tr"));
  let tbody = table.tBodies[0];
  let sortFunc = function (r1, r2) {
    switch (type) {
      case "number":
        return r1.cells[colIndex].innerText - r2.cells[colIndex].innerText;
        break;
      case "number":
      default:
        return r1.cells[colIndex].innerText > r2.cells[colIndex].innerText? 1: -1;
        break;
    }
  };
  trs = trs.sort(sortFunc);
  tbody.append(...trs); //追加已存在的元素,自动进行移动
}

全局提示示例:点击查看【codepen】

1.6、自定义事件

① 创建事件对象let event = new Event(type[, options]) ,使用Event构造函数,或者CustomEvent自定义事件(参数中有一个detail字段可存放自定义数据,在事件处理程序中通过event.detail使用),或其他事件对象MouseEvent、KeyboardEvent。

  • type:事件类型,可以是像 "click" 这样的字符串或任意。
  • options:具有两个可选属性的对象,是否冒泡bubbles(true=冒泡、false),是否取消默认行为ancelable: (true=阻止、false),默认值都是false。

②触发事件elem.dispatchEvent(event)

在你需要的地方调用elem.dispatchEvent(event)触发自定义事件,事件的处理程序和普通事件一样通过addEventListener添加,不支持on***


02、UI事件?

2.2、鼠标事件MouseEvent

鼠标事件(event)
click(event) 点击触发,通常是鼠标左键在一个元素上被按下并放开时
dblclick 双击触发事件
contextmenu 鼠标右键点击触发
mousedownmouseup 鼠标按下、弹起时触发
mousemove 鼠标在元素上移动时触发
onmouseovermouseout 鼠标移入、移出元素区域时触发
mouseenter、mouseleave 鼠标移入、移出元素区域时触发,与上面不同的是不会冒泡
dragstart、dragend 拖放事件(drag/dr?ɡ/拖)

鼠标事件响应顺序mouseenter mousemove mousedown mouseup click mouseleave



MouseEvent属性
button 鼠标按下的按钮:0=主按键/左键,1=滚轮中按键,2=次按键/右键
clientX / clientY 鼠标指针在窗口的 X 坐标、Y 坐标
pageX/pageY 鼠标指针在文档的 X 坐标、Y 坐标
ctrlKey、altKey、shiftKey 是否按下了CtrlAltShift按键,bool值
metaKey Mac中的 Cmd,同window的Ctrl
relatedTarget 次要(关联)目标,鼠标移入/出中使用,表示上一个target

鼠标点击位置动画示例:codepen



点击查看【codepen】

2.3、键盘事件KeyboardEvent

键盘事件(event)
keydown、keyup 键盘按键按下、松开时触发
过时的keypress

KeyboardEvent属性
code 按键编码(KeyA、KeyA、F1、0、Shift),物理按键的准确编码,比较稳定
key 按键值(A、a、F1、Digit0、ShiftLeft),正常看到的值,可能会随系统语言、输入环境变化
repeat 按键是否被一直按住,bool。按住时会一直触发keydown
ctrlKey、altKey、shiftKey 是否按下了CtrlAltShift按键,bool值
metaKey Mac中的 Cmd,同window的Ctrl

03、表单事件?

3.1、表单查找/取值

??获取表单

除了元素查找还有如下方式

  • 属性访问document.formName
  • forms属性document.forms为文档中所有表单集合。


??获取表单元素

  • form.name
  • form.elements集合,不用管元素的层级
    • form.elements.name,单个元素
    • form.elements['name'],元素名为name的集合,组合元素使用。
  • 子表单fieldset.elements

?表单和表单元素的双向引用:

??表单元素取值input.value表单元素大部分都是value取值/赋值,注意下面的:

  • input.checked,单选radio、多选checkbox通过checked取值/赋值,多个需要遍历取值。
  • textarea.value,??注意多行文本