一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。看完事件的相关内容,写的一篇笔记。
事件
1.0 了解事件
我们使用代码的方式和一个内容约定好一个行为,触发该行为是会有相应的代码执行。
1.0.1 事件三要素
- 事件源:和谁约定事件*(和谁触发不一样)*。
- 事件类型:约定了一个什么事件。
- 事件处理函数:当行为发生时,需要执行的函数。
这三个内容的目的是为了绑定事件,注册事件,就是提前做好约定。
1.1 事件绑定/解绑
1.1.1 事件绑定
-
DOM 0级事件
事件源.on事件类型 = 事件处理函数一个事件源的同一个事件类型,只能绑定一个事件处理函数。
div.onclick = ()=>{ console.log('我被点击了'); } -
DOM 2级事件(事件侦听器/事件监听器)
DOM 2级事件由于解绑的需要,所以需要将事件处理函数单独书写出来。
标准浏览器:
事件源.addEventListener('事件类型',事件处理函数)可以给一个事件源的同一个事件类型绑定多个事件处理函数,按照绑定顺序,顺序执行。
div.addEventListener('click',()=>{ console.log('我被点击了'); })IE低版本:
事件源.attachEvent('on事件类型',事件处理函数)可以给一个事件源的同一个事件类型绑定多个事件处理函数,按照绑定顺序,倒序执行。
1.1.2 事件解绑
-
DOM 0级事件
事件源.on事件类型 = null -
DOM 2级事件
标准浏览器:
事件源.removeEventListener('事件类型',事件处理函数)IE低版本:
事件源.deattachEvent('on事件类型',事件处理函数)<button id="but">解绑</button> <div id="div"></div> <script> function click(){ console.log('shot'); } div.addEventListener('click',click); but.onclick = ()=>{ div.removeEventListener('click',click) console.log('over'); } </script>
1.2 事件类型
js的原生事件没有大写字母
1.2.1 鼠标事件
依赖鼠标行为触发的时间。
- click 鼠标左键单击。
- dblclick 鼠标左键双击。
- contextmenu 鼠标右键单击。
- mousedown 鼠标按下(任何一个按键按下)。
- mouseup 鼠标抬起(任何一个按键按下后抬起)。
- mousemove 鼠标移动(光标只要位置改变就会触发,大概16ms一次)。
- mouseover/mouseout 鼠标移入/鼠标移出。移入子元素也会触发
- mouseenter/mouseleave 鼠标移入/鼠标移出。移入子元素不会触发
1.2.2 键盘事件
依赖键盘触发的事件。
所有元素都可以绑定键盘事件,但不是谁都能触发,一般可以有window/document/表单元素触发。
触发键盘事件一般不考虑中文输入法。
- keydown 键盘按键按下。
- keyup 键盘按键按下后抬起。
- keypress 键盘真实键入内容,或者回车键
1.2.3 浏览器事件
浏览器事件见 2.5 常见事件
1.2.4 表单事件
专门提供给表单的事件。
- focus 聚焦事件。
- blur 失焦事件。
- change 聚焦和失焦的时候内容不一样。
- input 只要表单元素输入或删除内容,就会触发。
- reset 重置,需要绑定给form标签才会触发。
- submit 提交,需要绑定给form标签才会触发。
1.2.5 触摸事件
移动端事件,只能在移动端设备使用(需要能够有触摸功能)
- touchstart 触摸开始,手触摸到屏幕的瞬间。
- touchmove 触摸移动,手在屏幕移动的时候。
- touchend 触摸结束,手在结束触摸屏幕的瞬间。
1.3 事件对象
记录本次事件触发的所有信息的对象数据类型。
1.3.1 获取事件对象
标准浏览器:
直接在事件处理函数书写一个形参,会在事件触发的时候,浏览器自动传递实参,即事件对象。
IE低版本:
直接使用window.event 来获取事件对象。
兼容:div.onclick = (event)=>{event = event || window.event;}
1.3.2 鼠标事件
-
clientX / clientY
光标相对于浏览器可视窗口左上角的坐标位置。
-
pageX / pageY
光标相对于文档流左上角的坐标位置。
-
offsetX / offsetY
光标相对于触发事件的元素左上角的坐标位置。
1.3.3 键盘事件
-
keyCode
按下的是哪一个按键。
-
组合按键
shiftKey / ctrlKey / alyKey / metaKey 都是布尔类型。
1.4 事件传播
当一个事件在浏览器中触发的时候,不光是在自己元素身上触发,是会传播出去的。
1.4.1 概念
当在一个元素身上触发行为的时候,会按照结构父级的顺序,向上直到window传递该行为。
真实的传播
首先 window 接收到行为, 按照结构级别逐层向下传递到准确触发事件的元素
在从准确触发事件的元素向上传递, 回到 window
在这个过程中, 每一个内容都接受了两次行为, 但是为什么事件处理函数只被调用了一次
因为浏览器的事件执行机制
捕获阶段(window -> 目标) 目标阶段 冒泡阶段(目标 -> window)
1.4.2 捕获 目标 冒泡
事件捕获:事件传播过程中,从window到目标的过程。
事件目标:准确触发事件的那个元素。
事件冒泡:事件传播过程中,从目标到window的过程。
-
如何获取事件目标?
在事件对象内有一个固定信息表示本次事件的事件目标
兼容:
var target = event.target || event.srcElement -
事件执行顺序
在IE低版本,只能按照冒泡的顺序执行。
在标准浏览器,默认在冒泡阶段执行,可以选择在捕获阶段执行。
DOM 0级事件无法修改,只能在DOM 2级事件中通过添加第三个参数执行。默认false,表示冒泡阶段执行,true表示捕获阶段执行。
1.4.3 阻止事件传播
标准浏览器:event.stopPropagation()
IE低版本:event.cancelBubble = true
兼容:try-catch,因为会报错,所有用try-catch
1.4.4 默认行为
不需要绑定事件,当触发行为就是出现效果的事情,叫做默认行为。
标准浏览器:event.preventDefault()
IE低版本:event.returnValue = false
兼容:try-catch
通用:在事件处理函数最后return false;,但是需要事件处理函数中不能出错。
1.4.5 事件委托
给多个元素绑定事件时,可将事件绑定给结构父级,当事件目标为自己时再执行。对于动态添加元素很友好。
原则:尽可能找到距离最近的公共的父级,尽可能找到在页面上不动的元素来委托。
<body>
<button>添加一个 li</button>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
// 0. 获取 ul 标签
// 因为 ul 是所有 li 共同的父级结构
var ul = document.querySelector('ul')
// 1. 给 ul 绑定点击事件
ul.onclick = function (e) {
// 处理事件对象兼容
e = e || window.event
// 处理事件目标兼容
var target = e.target || e.srcElement
// 2. 判断你点击的确实是 li
if (target.nodeName === 'LI') {
// 在控制台打印你点击的这个 li 的文本内容
console.log(target.innerText)
}
}
// 点击 button 按钮生成 li
var btn = document.querySelector('button')
btn.onclick = function () {
var li = document.createElement('li')
li.innerHTML = '我是新来的'
ul.appendChild(li)
}
</script>
</body>
1.x 总结
1.x.1 名词解释:
-
事件源: 绑定在 谁 身上的事件。
-
事件类型: 绑定 什么 事件。
-
事件处理函数: 当行为发生的时候, 执行的函数。
-
事件侦听器: DOM 2级 绑定事件的方式
标准浏览器: addEventListener()
IE 低版本: attachEvent()
-
事件解绑: 取消已经绑定好的事件
DOM 0级事件: 直接赋值为 null
标准浏览器中 DOM2级事件: removeEventListener()
IE 低版本中 DOM2级事件: deattchEvent()
注意: DOM2级事件的解绑, 在绑定的时候, 要把函数单独书写出来, 以函数名的形式进行绑定
-
事件传播: 按照结构父级的顺序, 从元素到 window 传递事件的行为。
-
事件捕获: 按照从 window 到 目标 的顺序传递行为的过程。
-
事件冒泡: 按照从 目标 到 window 的顺序传递行为的过程。
-
事件目标: 当事件触发的时候, 那个准确触发事件的元素。
标准浏览器: target
IE 低版本: srcElement
-
阻止事件传播: 不让事件继续传播, 不会触发父级结构的事件函数了
标准浏览器: stopPropagation()
IE 低版本: cancelBubble = true
-
阻止默认行为: 不让元素默认的行为出现
标准浏览器: preventDefault()
IE 低版本: returnValue = false
-
事件委托: 把自己的事件委托给共同的结构父级
在父级的事件内, 通过事件目标判断来决定执行什么内容
-
事件对象: 当事件触发的时候, 浏览器提供的一个对象数据类型
里面记录着本次事件的所有相关信息
标准浏览器: 形参的方式
IE 低版本: window.event
1.x.2 兼容性
-
DOM2级事件绑定
标准浏览器: 事件源.addEventListener('事件类型', 事件处理函数)
IE 低版本: 事件源.attachEvent('on事件类型', 事件处理函数)
-
DOM2级事件解绑
标准浏览器: 事件源.removeEventListener('事件类型', 事件处理函数)
IE 低版本: 事件源.detachEvent('on事件类型', 事件处理函数)
-
事件对象的获取
标准浏览器: 形参方式接受
IE 低版本: window.event
-
事件对象中的键盘编码
标准浏览器: 事件对象.keyCode
FIreFox < 20: 事件对象.which
-
事件目标的兼容:
标准浏览器: 事件对象.target
IE 低版本: 事件对象.srcElement
-
阻止事件传播:
标准浏览器: 事件对象.stopPropagation()
IE 低版本: 事件对象.cancelBubble = true
-
阻止默认行为:
标准浏览器: 事件对象.preventDefault()
IE 低版本: 事件对象.returnValue = false