事件
1.事件三要素
事件是有三部分组成,事件源、事件类型、事件处理程序。我们称之为事件三要素
事件源:事件被处罚的对象
var btn=document.querySelector('.btn');事件类型:如何处罚,什么事件,比如鼠标点击(onclick),还是鼠标经过,还是键盘按下
事件处理程序:通过一个函数赋值的方式完成
btn.onclick=function(){
alert('球芭比母涅牛');
}2.事件类型
2.1 鼠标事件
| 鼠标事件 | 触发条件 |
|---|---|
| onclick | 鼠标单击左键触发 |
| ondblclick | 鼠标双击左键触发 |
| onmouseover | 鼠标经过触发 |
| onmouseout | 移出离开触发 |
| onmousedown | 按下鼠标左键触发 |
| onmouseup | 松开鼠标左键触发 |
| onmousemove | 移动鼠标触发 |
| oncontextmenu | 鼠标右键单击事件 |
禁止鼠标右键菜单
document.addEventListener ('contextmenu', function(e){
e.preventDefault () ;
})2.2 键盘事件
| 事件 | 描述 |
|---|---|
| onkeydown | 键盘按下 |
| onkeyup | 键盘抬起 |
| onkeypress | 某个键盘按键被按下时触发 但是它不识别功能键比如ctrl shift箭头等 |
三个事件的执行顺序是: keydown -- keypress ---keyup
2.3 表单事件
| 事件 | 描述 |
|---|---|
| oninput | 表单元素的内容改变时触发 |
| onchange | 表单元素的内容改变并且失去焦点时触发 |
| onsubmit | 表单提交时触发 |
| onreset | 表单被重置后触发 |
| onblur | 表单失去焦点时触发 |
| onfocus | 表单获取焦点时触发 |
| onfocusin | 元素即将获取焦点时触发 |
| onfocusout | 元素即将失去焦点时触发 |
| onsearch | 用户向搜索域输入文本时触发 |
| onselect | 用户选取文本时触发,input、textarea |
| onsubmit | 表单提交时触发 |
2.4 框架/对象事件
| 事件 | 描述 |
|---|---|
| onabort | 图像的加载被中断。 ( <object>) |
| onbeforeunload | 该事件在即将离开页面(刷新或关闭)时触发 |
| onerror | 在加载文档或图像时发生错误。 ( <object>, <body>和 <frameset>) |
| onhashchange | 该事件在当前 URL 的锚部分发生修改时触发。也就是#后面的内容 |
| onload | 一张页面或一幅图像完成加载。 |
| onpageshow | 该事件在用户访问页面时触发 |
| onpagehide | 该事件在用户离开当前网页跳转到另外一个页面时触发 |
| onresize | 窗口或框架被重新调整大小。 |
| onscroll | 当文档被滚动时发生的事件。 |
| onunload | 用户退出页面。 ( <body> 和 <frameset>) |
2.5 剪贴板事件
| 事件 | 描述 |
|---|---|
| oncopy | 该事件在用户拷贝元素内容时触发 |
| oncut | 该事件在用户剪切元素内容时触发 |
| onpaste | 该事件在用户粘贴元素内容时触发 |
2.6 拖动事件
| 事件 | 描述 |
|---|---|
| ondrag | 该事件在元素正在拖动时触发 |
| ondragstart | 该事件在用户开始拖动元素时触发 |
| ondragend | 该事件在用户完成元素的拖动时触发 |
| ondragenter | 该事件在拖动的元素进入放置目标时触发 |
| ondragover | 该事件在拖动元素在放置目标上移动时触发 |
| ondragleave | 该事件在拖动元素离开放置目标时触发 |
| ondrop | 该事件在拖动元素放置在目标区域时触发 |
在拖放的过程中会触发以下事件:
- 在拖动目标上触发事件(源元素):此时
e.target是拖动目标元素- ondragstart - 用户开始拖动元素时触发
- ondrag - 元素正在拖动时触发
- ondragend - 用户完成元素拖动后触发
- 在释放目标上触发的事件:此时
e.target是释放目标元素- ondragenter - 当被鼠标拖动的对象进入其容器范围内时触发此事件
- ondragover - 当某被拖动的对象在另一对象容器范围内拖动时触发此事件
- ondragleave - 当被鼠标拖动的对象离开其容器范围内时触发此事件
- ondrop - 在一个拖动过程中,释放鼠标键时触发此事件
2.7 多媒体事件
| 事件 | 描述 |
|---|---|
| onabort | 事件在视频/音频(audio/video)终止加载时触发。 |
| oncanplay | 事件在用户可以开始播放视频/音频(audio/video)时触发。 |
| oncanplaythrough | 事件在视频/音频(audio/video)可以正常播放且无需停顿和缓冲时触发。 |
| ondurationchange | 事件在视频/音频(audio/video)的时长发生变化时触发。 |
| onemptied | 当期播放列表为空时触发 |
| onended | 事件在视频/音频(audio/video)播放结束时触发。 |
| onerror | 事件在视频/音频(audio/video)数据加载期间发生错误时触发。 |
| onloadeddata | 事件在浏览器加载视频/音频(audio/video)当前帧时触发触发。 |
| onloadedmetadata | 事件在指定视频/音频(audio/video)的元数据加载后触发。 |
| onloadstart | 事件在浏览器开始寻找指定视频/音频(audio/video)触发。 |
| onpause | 事件在视频/音频(audio/video)暂停时触发。 |
| onplay | 事件在视频/音频(audio/video)开始播放时触发。 |
| onplaying | 事件在视频/音频(audio/video)暂停或者在缓冲后准备重新开始播放时触发。 |
| onprogress | 事件在浏览器下载指定的视频/音频(audio/video)时触发。 |
| onratechange | 事件在视频/音频(audio/video)的播放速度发送改变时触发。 |
| onseeked | 事件在用户重新定位视频/音频(audio/video)的播放位置后触发。 |
| onseeking | 事件在用户开始重新定位视频/音频(audio/video)时触发。 |
| onstalled | 事件在浏览器获取媒体数据,但媒体数据不可用时触发。 |
| onsuspend | 事件在浏览器读取媒体数据中止时触发。 |
| ontimeupdate | 事件在当前的播放位置发送改变时触发。 |
| onvolumechange | 事件在音量发生改变时触发。 |
| onwaiting | 事件在视频由于要播放下一帧而需要缓冲时触发。 |
2.8 动画事件
| 事件 | 描述 |
|---|---|
| animationend | 该事件在 CSS 动画结束播放时触发 |
| animationiteration | 该事件在 CSS 动画重复播放时触发 |
| animationstart | 该事件在 CSS 动画开始播放时触发 |
2.9 过渡事件
| 事件 | 描述 |
|---|---|
| transitionend | 该事件在 CSS 完成过渡后触发。 |
2.10 其他事件
| 事件 | 描述 |
|---|---|
| onmessage | 该事件通过或者从对象(WebSocket, Web Worker, Event Source,BroadcastCannel 或者子 frame 或父窗口)接收到消息时触发 |
| onmousewheel | 已废弃。 使用 onwheel 事件替代 |
| ononline | 该事件在浏览器由离线变成在线时触发。 |
| onoffline | 该事件在浏览器由在线变成离线时触发。 |
| onpopstate | 该事件在窗口的浏览历史(history 对象)发生改变时触发。 |
| onshow | 该事件当 <menu> 元素在上下文菜单显示时触发 |
| onstorage | 该事件在 Web Storage(HTML 5 Web 存储)更新时触发 |
| ontoggle | 该事件在用户打开或关闭 <details> 元素时触发 |
| onwheel | 该事件在鼠标滚轮在元素上下滚动时触发 |
3.this
this在函数被调用的过程中,会在函数内部产生,在函数中的this有一个指向
this指向的是函数的调用者,也就是说这个函数由谁来调用,this就指向谁(this就是谁)
this是一个关键字,是在函数被调用(运行)时才会被绑定的,在不同的情况下this的指向是不同的
this的指向
- 事件处理函数中 this指向 事件源
- 普通函数中 this指向 window
- 对象中的方法(函数) this指向 对象本身
4.事件的绑定与移除
4.1 DOM0级事件
- 同一个节点同一事件只能设置一次,给一个节点绑定多个相同事件会后者覆盖前者
- 绑定DOM0级事件 语法:
元素对象.事件类型 = 事件处理函数
4.1.1 绑定
element.onclick = function(){
console.log("事件触发2")
}4.1.2 移除
直接赋值为null就行
elemeny.onclick = null;4.2 DOM2级事件(事件监听)
- 同一个节点同一事件可以绑定多个函数,按照绑定顺序执行
- 绑定DOM2级事件(添加事件监听) 语法:
element.addEventListener('click',function(){
console.log('我是第一个事件');
},false)4.2.1 主流浏览器绑定
元素对象.addEventListener(事件类型,事件处理函数,事件流【捕获/冒泡);参数:
- 参数1:事件类型传入时不写on,如果使用 onclick 就写 click
- 参数2:事件处理函数 function(){}
- 参数3:事件流【捕获/冒泡】 默认值是false表示冒泡,可以不传入 传入true表示捕获
4.2.2 兼容 ie6/7/8绑定
元素对象.attachEvent(事件类型,事件处理函数);参数:
- 参数1:事件类型传入时需要写oin,如果使用 onclick 就写 onclick
- 参数2:事件处理函数 function(){}
<div id="box"></div>
<script>
var oBox = document.querySelector("#box");
// 先触发
oBox.addEventListener('click',function(){
console.log('我是第一个事件');
},false)
// 后触发
oBox.addEventListener('click', function(){
console.log('我是第二个事件');
},false)
</script>4.2.3 移除
// 主流浏览器支持
元素对象.removeEventListener(事件类型,事件处理函数,事件流【捕获/冒泡】)
// 兼容 ie6\7\8
元素对象.detachEvent(事件类型,事件处理函数);举例
element.removeEventListener("click",fn2,false)5.事件对象
event对象代表事件的状态,跟事件相关的一系列信息的集合。事件对象主要有鼠标事件对象和键盘事件对象- 事件对象的产生一定要依赖于 事件的触发 才会 产生
5.1 获取事件对象
针对主流浏览器,事件处理函数的第一个形参就是事件对象
针对ie低版本浏览器,是通过 window对象的
event属性实现事件对象的获取
在IE低版本浏览器中(6/7/8)
标签对象.事件类型 = function() {
console.log(window.event); // 打印事件对象
}主流浏览器中
标签对象.事件类型 = function(e) { // 不一定要传入 e,ev、event 等均可
console.log(e); // 打印事件对象
}
// 在事件处理函数中,默认第一个形参就是事件对象兼容
标签对象.事件类型 = function(e) {
var e = e || window.event; // 通过不同浏览器的方式确定最终的时间对象的使用方式
console.log(e); // 打印事件对象
}5.2 事件对象通用属性
以下是事件对象常用的属性,通过e.key获取
| 属性 | 描述 | DOM |
|---|---|---|
| bubbles | 返回布尔值,指示事件是否是起泡事件类型。 | 2 |
| cancelable | 返回布尔值,指示事件是否可拥可取消的默认动作。 | 2 |
| currentTarget | 返回其事件监听器触发该事件的元素。 | 2 |
| eventPhase | 返回事件传播的当前阶段。 | 2 |
| target | 返回触发此事件的元素(事件的目标节点)。 | 2 |
| timeStamp | 返回事件生成的日期和时间。 | 2 |
| type | 返回当前 Event 对象表示的事件的名称。 |
5.3 鼠标事件对象
以下是鼠标事件对象常用的属性,通过e.key获取
| 属性 | 描述 |
|---|---|
| button | 返回当事件被触发时,哪个鼠标按钮被点击。 0:鼠标左键、1:鼠标中键、2:鼠标又键、 |
| clientX、clientY | 获取相对于浏览器显示窗口的左边和上边的位置 (不论是否存在滚动条,都是根据浏览器窗口左边和上边计算) |
| screenX、screenY | 获取到相对于电脑屏幕的左边和上边的位置。 |
| offsetX、offsetY | 获取相对于元素边框内左边和上边的位置,不包含边框 |
| pageX、pageY | 获取相对于整个页面的左边和上边的位置 (不论是否存在滚动条,都是根据页面的左边和上边计算) |
| relatedTarget | 返回与事件的目标节点相关的节点。 |
5.4 键盘事件对象
以下是键盘事件对象常用的属性,通过e.key获取
| 属性 | 描述 | DOM |
|---|---|---|
| altKey | 返回当事件被触发时,"ALT" 是否被按下。 | 2 |
| ctrlKey | 返回当事件被触发时,"CTRL" 键是否被按下。 | 2 |
| Location | 返回按键在设备上的位置 | 3 |
| charCode | 返回onkeypress事件触发键值的字母代码。 | 2 |
| key | 在按下按键时返回按键的标识符。 | 3 |
| keyCode | 返回onkeypress事件触发的键的值的字符代码,或者 onkeydown 或 onkeyup 事件的键的代码。 | 2 |
| which | 返回onkeypress事件触发的键的值的字符代码,或者 onkeydown 或 onkeyup 事件的键的代码。 | 2 |
| metaKey | 返回当事件被触发时,"meta" 键是否被按下。 | 2 |
| relatedTarget | 返回与事件的目标节点相关的节点。 | 2 |
| shiftKey | 返回当事件被触发时,"SHIFT" 键是否被按下。 | 2 |
5.3.1 按键编码keyCode
- 我们的键盘上每一个按键都有一个自己独立的编码
- 我们就是靠这个编码来确定我们按下的是哪个按键的
- 我们通过 event.keyCode或者envent.which来获取
- 因为 FireFox2.0不支持keycode所以要用which
- 兼容写法
var keycode = e.keycode || e.which;
document.onkeydown = function(ev){
var e = ev || window.event;
// 获取 按键编码的 兼容
var keycode = e.keycode || e.which;
console.log(keycode);
if(keycode === 82){
obox.style.background = 'red';
}else if(keycode === 66){
obox.style.background = 'blue';
}
}| 字母按键 | 键码 | 数字按键 | 键码 | 控制键/功能键 | 键码 | 标点符号 | 键码 |
|---|---|---|---|---|---|---|---|
| A | 65 | 0 (数字键盘) | 48 | ESC | 27 | ` | 192 |
| B | 66 | 1 (数字键盘) | 49 | F1 | 112 | - | 189 |
| C | 67 | 2 (数字键盘) | 50 | F2 | 113 | = | 187 |
| D | 68 | 3 (数字键盘) | 51 | F3 | 114 | [ | 219 |
| E | 69 | 4 (数字键盘) | 52 | F4 | 115 | ] | 221 |
| F | 70 | 5 (数字键盘) | 53 | F5 | 116 | ; | 186 |
| G | 71 | 6 (数字键盘) | 54 | F6 | 117 | ' | 222 |
| H | 72 | 7 (数字键盘) | 55 | F7 | 118 | \ | 220 |
| I | 73 | 8 (数字键盘) | 56 | F8 | 119 | , | 188 |
| J | 74 | 9 (数字键盘) | 57 | F9 | 120 | . | 190 |
| K | 75 | 0 (右侧小键盘) | 96 | F10 | 121 | / | 191 |
| L | 76 | 1 (右侧小键盘) | 97 | F11 | 122 | / (右侧小键盘) | 111 |
| M | 77 | 2 (右侧小键盘) | 98 | F12 | 123 | * (右侧小键盘) | 106 |
| N | 78 | 3 (右侧小键盘) | 99 | 退格键(Backspace) | 8 | - (右侧小键盘) | 109 |
| O | 79 | 4 (右侧小键盘) | 100 | Tab | 9 | + (右侧小键盘) | 107 |
| P | 80 | 5 (右侧小键盘) | 101 | Caps Lock | 20 | . (右侧小键盘) | 110 |
| Q | 81 | 6 (右侧小键盘) | 102 | 回车键(Enter) | 13 | ||
| R | 82 | 7 (右侧小键盘) | 103 | Shift | 16 | ||
| S | 83 | 8 (右侧小键盘) | 104 | Ctrl (Control) | 17 | ||
| T | 84 | 9 (右侧小键盘) | 105 | Alt | 18 | ||
| U | 85 | 空格键(Space) | 32 | ||||
| V | 86 | Clear | 12 | ||||
| W | 87 | Insert | 45 | ||||
| X | 88 | Delete | 46 | ||||
| Y | 89 | Home | 36 | ||||
| Z | 90 | End | 35 | ||||
| Page Up | 33 | ||||||
| Page Down | 34 | ||||||
| 方向键(←) | 37 | ||||||
| 方向键(↑) | 38 | ||||||
| 方向键(→) | 39 | ||||||
| 方向键(↓) | 40 |
5.3.2 组合按键
altKey:alt 键按下得到 true,否则得到 false
shiftKey:shift 键按下得到 true,否则得到 false
ctrlKey:ctrl 键按下得到 true,否则得到 false
用于设定 组合 按键
ctrl + 其他按键
shift + 其他按键
alt + 其他按键
ctrl + shift + 其他按键
ctrl + alt + 其他按键
......
注意 :其他按键只能有一个(也就是除了ctrl、alt、shift的其他案件)
document.onkeydown = function(ev){
var e = ev || window.event;
// 获取 按键编码的 兼容
var keycode = e.keycode || e.which;
if(e.ctrlKey && e.altKey && keycode === 88){
alert("按键为 ctrl 和 alt 和 X");
}
}6.事件流
6.1 概述:
事件流描述的是从页面接收事件顺序。当有层级关系(嵌套关系)的元素,都绑定了相同的事件类型在子元素触发了该事件后,同时也能触发父元素的该事件,这个就是事件流,也可以说是事件的传播
触发条件:
- 元素之间存在嵌套关系
- 父元素和子元素绑定了同类型的事件
事件流的种类:
- 事件冒泡、事件捕获
事件流的三个阶段:
捕获阶段:事件从Document节点自上而下向目标节点传播的阶段;
目标阶段:真正的目标节点正在处理事件的阶段;
冒泡阶段:事件从目标节点自下而上向Document节点传播的阶段。
6.2 事件冒泡
从具体的向不具体的传播,即事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的元素
子元素绑定事件,若父元素绑定同样的事件,就会一级一级往上触发,直到触发到docoment对象上
针对 DOM 0级事件 默认是冒泡,而且只有冒泡,无法改变
针对 DOM 2级事件 默认是冒泡
针对 高版本浏览器 默认是冒泡,但是可以改变
DOM 2级事件addEventListener 这个方法的第三个参数决定事件流
- 默认值为 false,表示 事件冒泡
- 如果设定值为 true,表示 事件捕获
针对 ie6、7、8低版本浏览器 默认是冒泡,而且只有冒泡,无法改变
6.3 事件捕获
从不具体的向具体的
事件捕获的思想是不太具体的节点应该更早的接收到事件,而最具体的节点应该最后接收到事件
事件捕获只存在于针对高版本浏览器绑定DOM2级事件是可以设置
- 给 addEventListener这个方法的第三个参数决定事件流
- 传入 true 表示 事件捕获
6.4 阻止事件冒泡
通过事件对象上的属性和方法实现
针对高版本浏览器
event.stopPropagation();
针对 ie6/7/8低版本浏览器
event.cancelBubble = true;
阻止事件冒泡的兼容写法
box.onclick = function(ev){
var e = ev || window.event;
e.stopPropagation?e.stopPropagation():e.cancelBubble = true;
}7.事件委托
7.1 什么是事件委托
- 所谓的事件委托,就是将要处理的事情委托给别人来完成。
- 实现:将子元素的事件委托给父元素绑定
7.2 为什么需要将事件委托
- 在工作中,我们经常需要动态增加节点,如果采用传统的绑定事件写法,对于新增的节点事件不会生效
7.3 采用事件委托
- 利用事件的事件流机制,点击子元素的时候,也会同步触发父元素的相同事件
- 所以我们就可以把子元素的事件委托给父元素来做
- 关键的核心是 使用 事件对象的target属性 判断 目标
7.4 target
target 是事件对象上的属性,表示点击的目标
当触发点击事件的时候,点击在哪个元素上,target就是哪个元素
兼容:在其他浏览器中 event.target,在IE浏览器中 event.srcElement
var target = e.target || e.srcElement;
返回结果是 点击的元素对象
通过
event.target.nodeName获取 标签大写名称,实现判断元素
ul.addEventListener('click',(e)=>{
if(e.target.nodeName==='LI'){
console.log('li被点击了')
}
})7.5 事件委托的好处
- 事件委托可以精准的控制事件的处理函数,并不会出现唐突的冒泡行为
- 事件委托非常的节省性能,而且使用方便,不需要批量注册事件
- 事件委托在处理异步结构的时候,可以不需要考虑异步的先后顺序(暂时未学习异步)
8.阻止浏览器默认行为
事件对象.preventDefault(); 针对 高版本浏览器生效
事件对象.returnValue = false; 针对 ie6/7/8低版本浏览器生效
阻止浏览器默认行为的 兼容
e.preventDefault?e.preventDefault():e.returnValue = false;另一种方法就是在事件函数最后 return false;
方便好记
var a1 = document.querySelector('#a1');
a1.onclick = function(ev){
var e = ev || window.event;
e.preventDefault?e.preventDefault():e.returnValue = false;
// return false;
}
document.oncontextmenu = function(ev){
var e = ev || window.event;
e.preventDefault?e.preventDefault():e.returnValue = false;
// return false;
}