DOM事件
DOM(文档对象模型)结构是一个树型结构,当一个HTML元素产生一个事件时,该事件会在元素结点与根结点之间的路径传播,路径所经过的结点都会收到该事件,这个传播过程可称为DOM事件流。
DOM事件模型分为捕获和冒泡,当一个DOM事件发生后会经过
- 由外到内的捕获阶段(必须执行阶段,不可终止)
- 处理DOM事件的目标阶段
- 以及由内到外的冒泡阶段(所有冒泡都可以通过stopPagation函数来阻止冒泡)
//html
<div id='div1'>
<div id='div2'>
<div id='div3'></div>
</div>
</div>
//JavaScript
div3.addEventListener('click',(e)=>{
console.log(e.target)//用户操作元素
console.log(e.currentTarget)//用户监听元素
},false)//第三个值默认false,指定函数在冒泡阶段执行,为true,则设置函数在捕获阶段执行
- 点击了div3相当于点击了div2和div1,如果想不触发div2和div1,需设置执行完后执行e.target.stopPagation()来阻止冒泡
- 事件执行顺序为先捕获在冒泡
- 当只有div3被监听(不考虑div1和div2),且在捕获和冒泡阶段都进行了事件监听时,事件谁先被监听谁就先执行
自定义事件
//自定义事件
div2.addEventListener('click',()=>{
//CustomEvent用于创建一个新对象事件
const event = new new CustomEvent(typeArg, customEventInit)
//设置自定义事件允许冒泡
bubbles = true
//设置自定义事件允许取消
cancelable = true
//将事件放到div2中
div2.dispatchEvent(event)
})
事件委托
由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的委托,可以用来监听已存在或者不存在元素,可以节约内存
//html
<div id=parent>
<p><span></span><p>
</div>
//JS
parent.addEventListener('click', function (event) {
//监听不存在的子元素
if (event.target.tagName.toLowerCase() === 'bottom') {
// some code
}
//监听已存在的子元素
if (event.target.tagName.toLowerCase() === 'p') {
//注意p中有个span,event.target是指用户操作元素,所以点击span将不触发事件
//处理方法,用循环获取父元素,看父元素中有没有满足条件得元素,直到父节点等于用户监听元素为止
let el = e.target
while (!el.matches('p')) {
if (el === e.currentTarget) {
el = null
break
}
el = el.parentNode
}
if(el)console.log(111)
}
});
怎么阻止默认行为和事件冒泡
document.querySelector("#id-checkbox").addEventListener("click", function(event) {
event.preventDefault()//阻止默认的点击事件执行
event.stopPropagation()//阻止事件冒泡,它不能防止任何默认行为的发生,它可以阻止事件触发后默认动作的发生
}, false);