DOM2级事件的核心运行机制
2020-08-28 本文已影响0人
江平路
image.png
image.png4、
1、DOM0 事件绑定
- 语法:元素.on事件行为=function(){}
- 原理:给元素的私有属性赋值,当事件触发,浏览器会帮我们把赋的值执行,但是这样也导致 “只能给当前元素某一个事件行为绑定一个方法”
box.onclick = function () {
console.log('哈哈哈~~');
}
box.onclick = function () {
console.log('呵呵呵~~');
}
复制代码
只输出后面的:
image.png
- 移除
box.onclick = function () {
console.log('哈哈哈~~');
//=>移除事件绑定:DOM0直接赋值为null即可
box.onclick = null;
}
复制代码
2、DOM2 事件绑定
-
语法:
- 元素.addEventListener(事件行为,function(){},true/false)
- true/false 可以省略,默认是false
- IE6~8中:元素.attachEvent('on事件行为',function(){})
- 元素.addEventListener(事件行为,function(){},true/false)
-
原理:
- 基于原型链查找机制,找到EventTarget.prototype上的方法并且执行,此方法执行,会把给当前元素某个事件行为绑定的所有方法,存放到浏览器默认的事件池中(绑定几个方法,会向事件池存储几个);
- 当事件行为触发,会把事件池中存储的对应方法,依次按照顺序执行 “给当前元素某一个事件行为绑定多个不同方法”
事件池特点:
- 基于addEventListener向事件池增加方法,存在去重的机制 “同一个元素,同一个事件类型,在事件池中只能存储一遍这个方法,不能重复存储”
box.addEventListener('click', function () {
console.log('哈哈哈~~');
}, false);
box.addEventListener('click', function () {
console.log('呵呵呵~~');
}, false);
复制代码
两个都能输出:
image.png- 绑定注意点:DOM2事件绑定的时候,我们一般都采用实名函数
- 目的:这样可以基于实名函数去移除事件绑定
- 语法:box.addEventListener('click', fn, false);
function fn1(){ console.log(1); }
function fn2(){ console.log(2); }
function fn3(){ console.log(3); }
box.addEventListener('click', fn2, false);
box.addEventListener('click', fn3, false);
box.addEventListener('click', fn1, false);
//=>基于addEventListener向事件池增加方法,存在去重的机制 “同一个元素,同一个事件类型,在事件池中只能存储一遍这个方法,不能重复存储”
box.addEventListener('click', fn1, false); // 所以此步跳过,不再存储
box.addEventListener('mouseover', fn1, false);
image.png
- 移除绑定:从事件池中移除,所以需要指定好事件类型、方法等信息(要和绑定的时候一样才可以移除)
- 语法:box.removeEventListener('click', fn, false)
function fn() {
console.log('哈哈哈~~');
//=>移除事件绑定:从事件池中移除,所以需要指定好事件类型、方法等信息(要和绑定的时候一样才可以移除)
box.removeEventListener('click', fn, false);
}
box.addEventListener('click', fn, false);
3、特别注意的几点
- -1)DOM0和DOM2可以混在一起用:执行的顺序以绑定的顺序为主
box.addEventListener('click', function () {
console.log('哔咔哔咔~~');
});
box.onclick = function () {
console.log('哇咔咔~~');
}
box.addEventListener('click', function () {
console.log('call~~');
});
image.png
- -2)DOM0 比 DOM2 快
- -3)DOM0中能做事件绑定的事件行为,DOM2都支持;DOM2里面一些事件,DOM0不一定能处理绑定,例如:transitionend、DOMContentLoaded...
box.style.transition = 'opacity 1s';
box.ontransitionend = function () {
console.log('哇咔咔~~');
}
box.addEventListener('transitionend', function () {
console.log('哇咔咔~~');
});
window.addEventListener('load', function () {
//=>所有资源都加载完成触发
console.log('LOAD');
});
window.addEventListener('DOMContentLoaded', function () {
//=>只要DOM结构加载完就会触发
console.log('DOMContentLoaded');
});
//=>$(document).ready(function(){})
$(function () {
//=>JQ中的这个处理(DOM结构加载完触发)采用的就是DOMContentLoaded事件,并且依托DOM2事件绑定来处理,所以同一个页面中,此操作可以被使用多次
});
/* JQ中的事件绑定采用的都是DOM2事件绑定,例如:on/off/one */
复制代码
4、window.onload
和 $(document).ready()
的区别
- -1)$(document).ready()
- 采用的是DOM2事件绑定,监听的是
DOMContentLoaded
这个事件,所以只要DOM结构加载完成就会被触发执行, - 而且同一个页面中可以使用多次(绑定不同的方法,因为基于DOM2事件池绑定机制完成的)
- 采用的是DOM2事件绑定,监听的是
- -2)window.onload
- 必须等待所有资源都加载完成才会被触发执行,采用DOM0事件绑定,同一个页面只能绑定一次(一个方法),
- 想绑定多个也需要改为
window.addEventListener('load', function () {})
DOM2绑定方式
5、DOM0 和 DOM2 的传播的区别
- DOM0 绑定的方法,只能在目标阶段和冒泡阶段触发执行
- DOM2绑定的方法,我们可以控制在捕获阶段执行
- 元素.addEventListener(事件行为,function(){},true/false)
- 第三个参数:不写 默认是 false
- false:代表在冒泡阶段执行此方法
- true:代表在捕获阶段执行此方法(基本没用过)
浏览器常用的事件行为
image.png1、鼠标事件
鼠标点击:鼠标按下弹起算一次点击
- onclick:点击(移动端click被识别为单击)
- ondblclick:双击(大概是在 300ms 之间点击两次)
- oncontextmenu:右键点击
鼠标按下:不分左右键或者滚轮,只要按下/抬起就会触发
- onmousedown:鼠标按下
- onmouseup:鼠标抬起
鼠标滚动
- onmousewhell:鼠标滚轮滚动
鼠标移动:鼠标尖端移动触发
- onmousemove:鼠标移动
鼠标经过
- onmouseout:鼠标滑出
- onmouseover:鼠标滑过(在表面经过即可)
鼠标进入
- onmouseenter:鼠标进入(进入到里面)
- onmouseleave:鼠标离开
思考:onmouseover 和 onmouseenter 的区别
image.png- mouseover/mouseout 存在冒泡机制。划过和划出(鼠标在谁身上,相当于划过谁)
- mouseenter/mouseleave 不存在冒泡传播机制。进入和离开。
如何选用:项目中,如果一个容器中有后代元素,想要鼠标进入和离开做啥事,我们一般都用mouseenter和mouseleave。
image.png2、键盘事件
能绑定键盘事件的有:
input
、textarea
、window
、document.body
等
- 如果想给不能编辑的元素绑定键盘事件,需要给这个元素加一个:
contenteditable = "true"
- onkeydown:按下某个键
- onkeyup:抬起某个键
- onkeypress:除Shift/Fn/CapsLock键以外,其它键按住(连续触发)
3、表单事件
使用范围:input ......
- onfocus:获取焦点(光标进入input时,触发事件)
- onblur:失去焦点(光标离开input时,触发事件)
- oninput:内容改变(只要内容发生改变就会触发)
- onchange:内容改变(并且失焦的时候才会触发)
4、音视频事件
使用范围:音频、视频
- canplay:可以播放(资源没有加载完,播放中可能会卡顿)
- canplaythrough:可以播放(资源已经加载完,播放中不会卡顿)
- play:开始播放
- playing:播放中
- pause:暂停播放
5、系统事件
其它常用事件
- window.onscroll:页面滚动
- window.onresize:页面大小发生改变的时候触发
- window.onload:页面资源加载完毕之后触发
- img.onload :图片加载完成
- window.onbeforeunload:当前页面关闭之前
- window.onerror:资源加载失败
6、移动端事件
单手指事件模型 Touch
- ontouchstart:手指碰到屏幕(手指按下)
- ontouchmove:手指在屏幕上移动
- ontouchend:手指离开屏幕(手指松开)
- ontouchcancel:操作取消(一般应用于非正常状态下操作结束)
多手指事件模型 Gesture
- ongesturestart:手指碰到屏幕(手指按下)
- ongesturechange / ongestureupdate:手指在屏幕上移动
- ongestureend:手指离开屏幕(手指松开)
- ongesturecancel:操作取消(一般应用于非正常状态下操作结束)
7、其他事件
- transitionend:动画过渡完成
- onreadystatechange:AJAX请求状态改变事件
- ......
事件行为还有很多,这里我们暂时列举这些;更多的内容可以参考 MDN,事件参考; 或者可以查看元素的属性(属性中onxxx就是元素拥有的事件行为)