JS事件理解

2020-04-29  本文已影响0人  xiaoguo16

先举一个例子,有一个父节点parent包含了一个子节点child,如下:

.outer{
        border: 1px solid #ccc;
        padding: 10px;
}
.inner{
        border: 1px solid red;
        padding: 10px;
 }
<div id="parent" class='outer'>
        parent
        <div id="child" class='inner'>child</div>
 </div>
 const parentDom = document.getElementById('parent')
 const childDom = document.getElementById('child')
image.png

事件流理解

DOM事件流包括三个阶段:

如果对上述例子中的parent和child都定义click事件:

       parentDom.addEventListener('click', (e)=>{
            console.log('父节点点击')
        })
        childDom.addEventListener('click', (e)=>{
            console.log('子节点点击')
        })

如果点击父节点,则只会调用父节点中定义的事件,打印内容如下:


image.png

如果点击子节点,则事件捕获到具体的目标对象(子节点)后,调用对应的事件,然后进入冒泡阶段,父节点也会调用其click事件,因此打印内容如下。


image.png

阻止事件冒泡

在上述问题中,如果我们点击子节点时,只想触发子节点的事件,不让父节点的事件发生,则需要阻止事件冒泡。

        childDom.addEventListener('click', (e)=>{
            e.stopPropagation()
            console.log('子节点点击')
        })

点击子节点时,控制台打印内容:


image.png

如上所示,使用event对象的stopPropagation方法可以阻止事件冒泡,这样就不会触发父节点的click事件。
还有一个阻止事件冒泡的方法是stopImmediatePropagation,它与stopPropagation的区别为:

如下,对childDom定义了两个click事件的话,stopImmediatePropagation会阻止后面的事件调用,不会打印出 '子节点点击第二次' ,而stopPropagation不会阻止,两个都会打印。

        childDom.addEventListener('click', (e)=>{
            // e.stopPropagation()
            e.stopImmediatePropagation()
            console.log('子节点点击第一次')
        })
        childDom.addEventListener('click', (e)=>{
            console.log('子节点点击第二次')
        })

阻止事件的默认行为

有些事件会有一些默认的行为,比如a标签点击时会导航到href指定的url,如果想阻止这些默认行为,可以使用event的preventDefalut属性。

<a href='' id='clickA'>点击</a>
const aDom = document.getElementById('clickA')
aDom.addEventListener('click', (e)=>{
     e.preventDefault()
})

上述这个例子点击a标签时就不会出现页面刷一下的情况。

target与currentTarget区别

target是事件的目标,即上述事件流中处于目标阶段的DOM节点。currentTarget是绑定事件的DOM节点,其实可以想象为bindTarget。如下:

        parentDom.addEventListener('click', (e)=>{
            console.log(e.target,e.currentTarget)
            console.log('父节点点击')
        })
        childDom.addEventListener('click', (e)=>{
            console.log('子节点点击')
        })

则点击子节点时,打印如下:


image.png

从上可知,target对象是child的DOM节点,而currentTarget是绑定事件的parent的DOM节点。

上一篇 下一篇

猜你喜欢

热点阅读