DOM事件级别
- DOM 0级
var btn = document.getElementById('btn');
btn.onclick = function() {
alert('Hello World');
}
复制代码
DOM0级事件处理程序的缺点在于一个处理程序无法同时绑定多个处理函数,比如我还想在按钮点击事件上加上另外一个函数。
- DOM 2级 DOM2级事件在DOM0级事件的基础上弥补了一个处理程序无法同时绑定多个处理函数的缺点,允许给一个处理程序添加多个处理函数。
btn.addEventListener('click', showFn, false);
复制代码
DOM2级事件定义了addEventListener和removeEventListener两个方法,分别用来绑定和解绑事件,方法中包含3个参数,分别是绑定的事件处理属性名称(不包含on)、处理函数和是否在捕获时执行事件处理函数
需要注意的是IE8级以下版本不支持addEventListener和removeEventListener,需要用attachEvent和detachEvent来实现:
btn.attachEvent('onclick', showFn); // 绑定事件
btn.detachEvent('onclick', showFn); // 解绑事件
复制代码
- DOM 3级 DOM3级事件在DOM2级事件的基础上添加了更多的事件类型,全部类型如下:
- UI事件,当用户与页面上的元素交互时触发,如:load、scroll
- 焦点事件,当元素获得或失去焦点时触发,如:blur、focus
- 鼠标事件,当用户通过鼠标在页面执行操作时触发如:dbclick、mouseup
- 滚轮事件,当使用鼠标滚轮或类似设备时触发,如:mousewheel
- 文本事件,当在文档中输入文本时触发,如:textInput
- 键盘事件,当用户通过键盘在页面上执行操作时触发,如:keydown、keypress
- 合成事件,当为IME(输入法编辑器)输入字符时触发,如:compositionstart
- 变动事件,当底层DOM结构发生变化时触发,如:DOMsubtreeModified
DOM事件模型
捕获 冒泡
DOM事件流
事件捕获阶段、处于目标阶段、事件冒泡阶段
当点击子元素时,如果父元素含有捕获事件,会先执行父元素的捕获事件,如果有多个捕获事件,按照捕获事件的添加顺序执行。执行完父元素的捕获事件后开始执行子元素的事件,子元素的事件,不管是冒泡事件还是捕获事件,会根据添加顺序执行;执行完子元素的事件后,如果父元素有冒泡事件,会根据父元素冒泡事件的添加顺序执行事件。
DOM事件捕获的具体流程
window -> document -> html -> body -> ... -> target
Event对象的常见应用
-
event.preventDefault()
此方法用来阻止默认的事件,比如阻止a标签的跳转
-
event.stopPropagation()
阻止冒泡;让事件停留在当前dom而不会向上传递
-
event.stopImmediatePropagation()
和stopPropagation相比,stopImmediatePropagation同样可以阻止事件的传播,不同点在于其还可以把这个元素绑定的同类型事件也阻止了。如:
var go = document.getElementById('go'); function goFn(event) { event.preventDefault(); event.stopImmediatePropagation(); // 阻止事件冒泡并阻止同类型事件 console.log('我没有跳转!'); } function goFn2(event) { console.log('我是同类型事件!'); } go.addEventListener('click', goFn, false); go.addEventListener('click', goFn2, false); 复制代码
我们在a链接上继续加了一个点击事件,如果我们在goFn方法中添加了stopImmediatePropagation方法,那么goFn2方法将不会被执行,同时也不会将点击事件冒泡至上层。
-
event.target
target 事件属性可返回事件的目标节点(触发该事件的节点),如生成事件的元素、文档或窗口。
-
event.currentTarget
此属性返回当前事件所绑定的对象。
自定义事件
<!--自定义事件Event-->
<script>
var event1 = new Event('myEvent');
var box = document.getElementsByClassName('event-custom-box')[0];
box.addEventListener('myEvent',function () {
console.log('event1');
})
setTimeout(function () {
box.dispatchEvent(event1);
},1000)
</script>
<!--自定义事件CustomEvent-->
<section class="event-custom-box2">自定义custom事件</section>
<script>
var event2 = new CustomEvent('myCustomEvent',{detail:{name:'lalaBao'}})
var box2 = document.getElementsByClassName('event-custom-box2')[0];
box2.addEventListener('myCustomEvent',function (event) {
console.log(event.detail.name);//lalaBao
})
setTimeout(function () {
box2.dispatchEvent(event2);
},1000)
</script>
复制代码
CustomEvent 和 Event的区别,CustomEvent可以给事件绑定数据,传入对象的detail属性会被绑定到event上
Event工具
// 事件工具辅助类的封装
var EventHelper = {
// 添加事件
addEvent: function (element, type, func) {
if(element.addEventListener){
element.addEventListener(type, func, false);
}else if (element.attachEvent) {
// 兼容IE、Opera等老版本浏览器的事件处理
element.attachEvent('on' + type, func);
}else {
// 如果以上两种方式都不支持,那就直接在元素对象的属性上绑定事件处理
element['on' + type] = func;
}
},
// 删除事件
removeEvent: function (element, type, func) {
if(element.removeEventListener){
element.removeEventListener(type, func, false);
}else if (element.attachEvent) {
element.detachEvent('on' + type, func);
}else {
element['on' + type] = null;
}
}
};
/*** 封装类对象的使用 ***/
// 添加事件
EventHelper.addEvent(domListenerObj, 'click', oneClick);
// 删除事件
EventHelper.removeEvent(domListenerObj, 'click', oneClick);
复制代码