Dom事件流
DOM2事件流分为3个阶段:事件捕获,到达目标和事件冒泡,事件捕获最先发生,为提前拦截事件提供了可能,然后,实际的目标元素接收到事件后,最后一个阶段是冒泡,最迟要在这个阶段响应事件。
实际目标(div元素)在补货阶段不会接收到事件,这是因为捕获阶段从document到html到body就结束,下一个阶段,即会在div元素上触发事件的‘到达目标阶段,通常在事处理中被认为是事件冒泡的第一部分,然后,冒泡阶段开始,事件反转传播到文档
事件处理程序
HTML事件处理程序:
这种交互能力是通过为onclick属性指定JavaScript代码值实现。
showMessage()函数时单独在script元素中定义,也可以在外部文件定义,作为事件处理程序的代码可以访问全局作用域中的一切
1 | <script> |
DOM0事件处理程序
每个元素(包括window和document)都有通常小写的事件处理程序属性,比如onclick,只要把这个属性赋值为一个函数即可
1 | let btn=document.getElementById('myBtn'); |
所赋函数被视为元素的方法,因此,事件处理程序会在元素的作用域中运行,即this等于元素以这种方式添加事件处理程序时注册在事件流的冒泡阶段
通过将事件处理程序属性的值设置为null,可以移除通过Dom0添加的事件处理程序
DOM2事件处理程序
DOM2 Events为事件处理程序的赋值和移除定义了两个方法:addEventListener()和removeEventListener(),它们接收3个参数:事件名,事件处理函数和一个布尔值,true表示在捕获阶段调用事件处理程序,false(默认值)表示在冒泡阶段调用事件处理程序
1 | let btn=document.getElementById("myBtn") |
使用DOM2的主要优势是可以为同一个事件添加多个事件处理程序
通过addEventListener()添加的事件处理程序通过removeEventListener()移除要传入与添加时同样的参数,因此无法使用addEventListener()添加的匿名函数移除
1 | let btn=document.getElementById("myBtn") |
1 | let handler=()=>{ |
事件对象
DOM事件对象
event对象时传给事件处理程序唯一参数
在事件处理程序内部,this对象始终等于currentTarget的值,而target只包含事件的实际目标,如果事件处理程序直接添加在了意图目标,则this,currentTarget,target的值一样
如果添加在父结点上,则不一样
1 | document.body.onclick=function(e){ |
- this和currentTarget等于document.body:它是注册事件处理程序的元素
- target属性等于按钮本身:按钮时click的真正目标
- 由于按钮本身没有注册事件处理程序,因此click事件冒泡到document.body,触发了在它上面注册的处理程序
type属性可以处理多个事件
preventDefault()方法用于阻止特定事件的默认动作,比如链接的默认行为是在被单击时导航到href属性指定的URL,阻止这个导航可以在onclick事件处理程序中取消,通过preventDefault()取消默认行为,事件对象的cancleable属性被设为true
stopPropagation()方法用于立即阻止事件流在DOM结构中传播,取消后序事件的捕获或冒泡。
1 | let btn=document.getElementById("myBtn") |
由于click事件不会传播到document.body,因此onclick事件处理程序永远不会执行
eventPhase用于确定事件流所处阶段,如果事件处理程序在捕获阶段被调用,则eventphase等于1,到达目标阶段为2,冒泡阶段为3
1 | let btn=document.getElementById('myBtn') |