1、DOM事件级别
- dom0: element. function(){}
- dom1: (没有定义事件相关的内容)
- dom2: element.addEventListener(‘click’,function(){},true/false)
emoveEventListener():不能移除匿名添加的函数
只有2级DOM包含3个事件:事件捕获阶段、处于目标阶段和事件冒泡阶段 - dom3: element.addEventListener(‘keyup’,function(){}, true/false)
type类型更多
在IE8和和IE8以前, 通过attachEvent绑定的事件里面的this是window;
拓展:DOM2级绑定方式
addEventListener | attachEvent (IE中绑定) |
---|---|
dom.addEventListener(type, handler, boolean) | dom.attachEvent(type, handler) |
type: 字符串 事件类型 注意:是不带”on” | type: 事件类型 注意: 是带“on” |
boolean布尔值:true——捕获阶段;false——冒泡阶段(默认) | 没有第三个参数,不支持捕获阶段 |
this指向绑定事件的对象 | 指向window |
可绑定多个函数 | 可绑定多个函数 |
按绑定的事件顺序执行 | Dom0优先执行,后逆序执行事件 |
可与dom0同时存在 | 可与dom0同时存在 |
移除事件:dom.removeEventListener(type, handler, boolean) | detachEvent,无第三个参数 |
DOM0级同一个元素同一事件只能绑定一个函数,后面的会层叠前面的
解决兼容性问题
* bindEvent 可以实现多浏览器兼容事件
* @dom 要绑定事件的元素
* @type 事件类型
* @fn 要执行的事件函数
function bindEvent(dom, type, fn) {
// 使用能力检测, 查看浏览器支持哪一种能力
// 能力检测, 就是指“当一个对象读取一个属性的时候, 如果能够获取到,那么输出;
// 如果获取不到 会报出undefined 而不是报错的这个特点”
if (dom.addEventListener) {
// 说明是高级浏览器
dom.addEventListener(type, fn, false);
} else if (dom.attachEvent) {
// 说明是IE中的高版本
dom.attachEvent("on" + type, fn);
} else {
// 说明IE中的低版本, 或者一些不知名的浏览器
dom["on" + type] = fn;
}
}
2、DOM事件模型
捕获:从最不具体的元素接收到最具体的元素
冒泡:事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)
3、DOM事件捕获的具体流程
补充:捕获具体流程,从上到下,window→document→html→body→元素→目标元素
<div class="button" id="btn">按钮</div>
<script type="text/javascript">
var btn = document.getElementById("btn");
btn.addEventListener("click", function() {
console.log("btn")
}, true)
window.addEventListener("click", function() {
console.log("window")
}, true);
document.addEventListener("click", function() {
console.log("document")
}, true);
document.documentElement.addEventListener("click", function() {
console.log("html")
}, true);
document.body.addEventListener("click", function() {
console.log("body")
}, true);
</script>
4、DOM事件流
事件捕获阶段→目标阶段→事件冒泡阶段
5、event对象的常见应用
- event.preventDefault() 阻止默认行为
- event.stopPropagation() 阻止冒泡
- event.stopImmediatePropagation()阻止事件冒泡并同时阻止元素后面绑定的同类型事件
如图:p元素绑定了四个click事件,第二个console.log后代码书写了event.stopImmediatePropagation(),导致第三个和第四个事件被阻止 - event.currentTarget 返回绑定事件的元素
- event.target 返回触发事件的元素(可用于事件委托)
作用: 代码性能优化。不需要每个子元素都循环绑定同一个事件,给父元素统一处理。通过event.target判断触发元素,并做相关处理。
<ul id="parent">
<li class="child">1</li>
<li class="child">2</li>
<li class="child">3</li>
<li class="child">4</li>
</ul>
<script>
var parent = document.getElementById('parent');
parent.addEventListener('click',function (event) {
console.log("触发事件的元素target");
console.log(event.target);//点击哪个child就是哪个
console.log("绑定事件的元素currentTarget");
console.log(event.currentTarget);//parent
})
</script>
6、自定义事件
Event和CustomEvent两种方式
区别:CustomEvent可以给事件绑定数据,传入对象的detail属性会被绑定到event上
var box = document.getElementById('box');
//创建事件, Event是无法传递参数的
var event1 = new Event("capture");
// 传入的数据必须是{detail:}的形式
var event2 = new CustomEvent('bind',{detail:{str: "hello world"}})
// capture为事件类型,event为事件对象
box.addEventListener("capture", function() {
console.log("event1")
console.log("1000ms后")
})
box.dispatchEvent(event1);
box.addEventListener('bind',function (event) {
console.log("event2传入数据:" + event.detail.str);//hello world
})
setTimeout(function () {
box.dispatchEvent(event2);
},1000)
输出结果: