JavaScript入门⑧-事件总结大全
JavaScript入门系列目录
- JavaScript入门⑨-异步编程●异世界之旅
- JavaScript入门⑩-ES6归纳总结
01、事件基础
1.1、事件简介
事件(Event)是JavaScript的心脏,触发各种交互,让网页动起来。事件是浏览器网页可以监测到的行为,如页面加载、鼠标点击、键盘按键等。在这些事件中可以自定义事件处理程序,用于实现各种业务需求。
事件对象的继承关系:
常见的事件类型、事件如下:
| ?鼠标事件(event) | |
|---|---|
| click(event) | 点击触发,通常是鼠标左键在一个元素上被按下并放开时 |
| dblclick | 双击触发事件 |
| contextmenu | 鼠标右键点击触发 |
| mousedown、mouseup | 鼠标按下、弹起时触发 |
| mousemove | 鼠标在元素上移动时触发 |
| onmouseover、mouseout | 鼠标移入、移出元素区域时触发 |
| 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)可能尚未加载完成 - 如果遇到 标签,会执行(包括外部的资源)然后才继续后面的DOM加载,要注意!async、defer标记的除外(只支持外部js资源) |
| window.load | 文档完全加载完成,包括图片、样式都准备好了。可用于window、element |
| window.beforeunload | 当用户正在离开页面时,不可取消,好像也不能干什么。 |
| window.unload | 用户几乎已经离开了,同上 |
| doc.readystatechange | 文档状态变化时触发,可跟踪文档加载状态readyState |
| onerror | 加载出现错误,用于元素 |
| scroll | 滑动条滚动事件,具有滚动的视图元素。用于window、element |
| ?ClipboardEvent事件 | 事件参数对象clipboardData由于安全限制,方法无法使用 |
| cut,copy,paste | 剪切、拷贝、粘贴时触发 |
| ?e.clipboardData | 保存了一个DataTransfer对象,用于存放数据,该对象也用于拖放 |
| ?CSS事件(event) | |
| transitionend | 一个元素 CSS 动画完成时ele.addEventListener("transitionend", func) |
1.2、事件的绑定
① HTML事件:HTML中绑定(调用)事件处理程序,,注意加括号()。
② JS绑定事件(DOM-0级事件):button.onclick = function() {},和HTML绑定一样,只能绑定一个事件处理程序。不能用setAttribute设置事件,因为设置的是字符串值。
③ 注册事件(DOM-2级事件):
- ele.addEventListener(event,func[, options]) :注册事件,??推荐的常用方式,可添加多个事件处理程序,但同一个事件类型不可添加同一个handler对象。参数options为配置信息,如是否冒泡。
- ele.removeEventListener(event,func[, options]) :必须是与添加时相同(恒等)的参数,不可移除匿名函数事件。
④ 事件处理对象handleEvent
除了注册事件方法,还可用将一个包含handleEvent方法的对象注册到事件处理程序,触发事件时调用对象的handleEvent方法。so,只要对象中包含handleEvent方法即可,任何对象、类的实例都可以。
span
1.3、事件对象event
每一个事件处理程序都有一个event对象,内置了事件的详细信息。最基础的Event如下,还有很多继承事件对象。
使用event.preventDefault() 可以移除浏览器的默认事件行为,也可以用return false。
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):一般常用的是冒泡阶段,这更符合逻辑。
事件从目标元素上开始冒泡,逐级向上春波,直到根节点。几乎所有事件都会冒泡,除了个别的,如blur、focus没有冒泡。
事件流的两种传播方式其实是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 | 鼠标右键点击触发 |
| mousedown、mouseup | 鼠标按下、弹起时触发 |
| mousemove | 鼠标在元素上移动时触发 |
| onmouseover、mouseout | 鼠标移入、移出元素区域时触发 |
| 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 | 是否按下了Ctrl、Alt、Shift按键,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 | 是否按下了Ctrl、Alt、Shift按键,bool值 |
| metaKey | Mac中的 Cmd,同window的Ctrl |
03、表单事件?
3.1、表单查找/取值
??获取表单, 除了元素查找还有如下方式
- 属性访问:
document.formName, - forms属性:
document.forms为文档中所有表单集合。
??获取表单元素:
form.nameform.elements集合,不用管元素的层级- form.elements.name,单个元素
- form.elements['name'],元素名为
name的集合,组合元素使用。
- 子表单
fieldset.elements
?表单和表单元素的双向引用:
??表单元素取值:input.value,表单元素大部分都是value取值/赋值,注意下面的:
- input.checked,单选
radio、多选checkbox通过checked取值/赋值,多个需要遍历取值。 - textarea.value,??注意多行文本
是通过value取值,而不是innerHTML。 - 下拉框select:select.options =
的子元素的集合- 单选:
select.value、select.selectedIndex - 多选:遍历
options取值,Array.from(select.options).filter(op=>op.select).map(op=>op.value);
- 单选:
??提交表单:
- document.loginForm.submit():表单的
submit()方法提交,完全自主控制,推荐食用。 - submit按钮+事件onclick=return 校验函数():校验函数校验表单数据,返回true提交表单,否则不提交
- submit按钮+form的事件onsubmit=return 校验函数():功能和用法基本同上。
3.2、表单事件
| ?表单事件(event) | |
|---|---|
| blur(event)、focusout() | 元素失去焦点,blur不会冒泡 (blue /bl??r/ 模糊 /不乐/) |
| focus、focusin | 元素获取焦点时触发,focus不会冒泡 |
| from.submit | 提交表单form时触发,可用于表单校验 |
| change | 值发生变化时触发,文本框是在值变化且失去焦点是才触发 |
| input | 输入值改变时触发。event.preventDefault()无法阻止,因为已经改变了 |
| ?方法-聚焦 | |
| elem.focus() | 设置元素获得焦点 |
| elem.blur() | 设置元素失去焦点 |
可编辑单元格的表格示例:codepen
??版权申明:版权所有@安木夕,本文内容仅供学习,欢迎指正、交流,转载请注明出处!原文编辑地址-语雀