0%

DOM事件

Dom事件流

DOM2事件流分为3个阶段:事件捕获,到达目标和事件冒泡,事件捕获最先发生,为提前拦截事件提供了可能,然后,实际的目标元素接收到事件后,最后一个阶段是冒泡,最迟要在这个阶段响应事件。

实际目标(div元素)在补货阶段不会接收到事件,这是因为捕获阶段从document到html到body就结束,下一个阶段,即会在div元素上触发事件的‘到达目标阶段,通常在事处理中被认为是事件冒泡的第一部分,然后,冒泡阶段开始,事件反转传播到文档

事件处理程序

HTML事件处理程序:

这种交互能力是通过为onclick属性指定JavaScript代码值实现。

showMessage()函数时单独在script元素中定义,也可以在外部文件定义,作为事件处理程序的代码可以访问全局作用域中的一切

1
2
3
4
5
6
<script>
function showMessage(){
console.log('hello world')
}
</script>
<input type='button' value='Click me' onclick="showMessage()"/>

DOM0事件处理程序

每个元素(包括window和document)都有通常小写的事件处理程序属性,比如onclick,只要把这个属性赋值为一个函数即可

1
2
3
4
5
let btn=document.getElementById('myBtn');
btn.onclick=function(){
console.log(this.id)//myBtn

}

所赋函数被视为元素的方法,因此,事件处理程序会在元素的作用域中运行,即this等于元素以这种方式添加事件处理程序时注册在事件流的冒泡阶段

通过将事件处理程序属性的值设置为null,可以移除通过Dom0添加的事件处理程序

DOM2事件处理程序

DOM2 Events为事件处理程序的赋值和移除定义了两个方法:addEventListener()和removeEventListener(),它们接收3个参数:事件名,事件处理函数和一个布尔值,true表示在捕获阶段调用事件处理程序,false(默认值)表示在冒泡阶段调用事件处理程序

1
2
3
4
let btn=document.getElementById("myBtn")
btn.addEventListener('click',()=>{
console.log(this.id)
},false)

使用DOM2的主要优势是可以为同一个事件添加多个事件处理程序

通过addEventListener()添加的事件处理程序通过removeEventListener()移除要传入与添加时同样的参数,因此无法使用addEventListener()添加的匿名函数移除

1
2
3
4
5
6
7
8
let btn=document.getElementById("myBtn")
btn.addEventListener('click',()=>{
console.log(this.id)
},false)
btn.removeEventListener('click',()=>{
console.log(this.id)
},false)//没有效果

1
2
3
4
5
6
let handler=()=>{
console.log(this.id)
}
let btn=document.getElementById("myBtn")
btn.addEventListener('click',handler,false);
btn.removeEventListener('click',handler,false)//有效果

事件对象

DOM事件对象

event对象时传给事件处理程序唯一参数

2

在事件处理程序内部,this对象始终等于currentTarget的值,而target只包含事件的实际目标,如果事件处理程序直接添加在了意图目标,则this,currentTarget,target的值一样

如果添加在父结点上,则不一样

1
2
3
4
5
document.body.onclick=function(e){
console.log(e.currentTarget===document.body);//true
console.log(this===document.body)//true
console.log(e.target===document.getElementById('myBtn'))//true
}
  1. this和currentTarget等于document.body:它是注册事件处理程序的元素
  2. target属性等于按钮本身:按钮时click的真正目标
  3. 由于按钮本身没有注册事件处理程序,因此click事件冒泡到document.body,触发了在它上面注册的处理程序

type属性可以处理多个事件

preventDefault()方法用于阻止特定事件的默认动作,比如链接的默认行为是在被单击时导航到href属性指定的URL,阻止这个导航可以在onclick事件处理程序中取消,通过preventDefault()取消默认行为,事件对象的cancleable属性被设为true

stopPropagation()方法用于立即阻止事件流在DOM结构中传播,取消后序事件的捕获或冒泡。

1
2
3
4
5
6
7
8
9
let btn=document.getElementById("myBtn")
btn.addEventListener('click',()=>{
console.log(this.id)
event.stopPropagation();
})
document.body.onclick=function(){
console.log('body click')
}

由于click事件不会传播到document.body,因此onclick事件处理程序永远不会执行

eventPhase用于确定事件流所处阶段,如果事件处理程序在捕获阶段被调用,则eventphase等于1,到达目标阶段为2,冒泡阶段为3

1
2
3
4
5
6
7
8
9
10
11
12
let btn=document.getElementById('myBtn')
btn.onclick=function(e){
console.log(e.eventPhase);//2
}
document.body.addEventListener('click',(e)=>{
console.log(e.eventPhase);//1
})
document.body.onclick=function(e){
console.log(e.eventPhase);//3


}