事件冒泡

在下面代码中,当我们点击按钮时,父元素的 div 也能接收到点击事件。这便是事件冒泡, 冒泡就是事件会依次传递给父元素,父元素的父元素,就像水中往上冒的气泡一样

<div id="outer">
    <button id="btn">点我试一试</button>
</div>
<script>
    outer.onclick = function () {
        alert("click outer")
    }

    btn.onclick = function () {
        alert("click btn")
    }
</script>
<style>
    #outer {
        width: max-content;

        padding: 20px;
        background-color: pink;
    }
</style>

$$demo

<div id="outer"> <button id="btn">点我试一试</button> </div> <script> outer.onclick = function () { alert("click outer") }

btn.onclick = function () {
    alert("click btn")
}

</script> <style> #outer { width: max-content;

    padding: 20px;
    background-color: pink;
}

</style>

$$

$$tip

绝大部分事件都会冒泡,当然也有一些不会冒泡的, 比如 focus

$$

this、target、currentTarget

  • this:指向绑定事件的元素。
  • currentTarget:指向绑定事件的元素。
  • target:指向触发事件的元素。
<div id="outer">
    <button id="btn">点我试一试</button>
</div>
<script>
    outer.onclick = function (event) {
        alert(`outer - this.id: ${this.id}`) // outer
        alert(`outer - event.target.id: ${event.target.id}`) // btn
    }

    btn.onclick = function (event) {
        alert(`btn - this.id: ${this.id}`) // btn
        alert(`btn - event.target.id: ${event.target.id}`) // btn
    }
</script>
<style>
    #outer {
        width: max-content;

        padding: 20px;
        background-color: pink;
    }
</style>

$$demo

<div id="outer"> <button id="btn">点我试一试</button> </div> <script> outer.onclick = function (event) { alert(outer - this.id: ${this.id}) // outer alert(outer - event.currentTarget.id: ${event.currentTarget.id}) // outer alert(outer - event.target.id: ${event.target.id}) // btn }

btn.onclick = function (event) {
    alert(`btn - this.id: ${this.id}`) // btn
    alert(`btn - event.currentTarget.id: ${event.currentTarget.id}`) // btn
    alert(`btn - event.target.id: ${event.target.id}`) // btn
}

</script> <style> #outer { width: max-content;

    padding: 20px;
    background-color: pink;
}

</style>

$$

停止冒泡

使用 event.stopPropagation()可以阻止事件的冒泡。

<div id="outer">
    <button id="btn">点我试一试</button>
</div>
<script>
    outer.onclick = function (event) {
        alert("click outer") // 不执行
    }

    btn.onclick = function (event) {
        event.stopPropagation() // 阻止冒泡
        alert("click btn")
    }
</script>
<style>
    #outer {
        width: max-content;

        padding: 20px;
        background-color: pink;
    }
</style>

$$demo

<div id="outer"> <button id="btn">点我试一试</button> </div> <script> outer.onclick = function (event) { alert("click outer") // 不执行 }

btn.onclick = function (event) {
    event.stopPropagation() // 阻止冒泡
    alert("click btn")
}

</script> <style> #outer { width: max-content;

    padding: 20px;
    background-color: pink;
}

</style>

$$

$$warning

非必要不要阻止事件的冒泡,不然可能会影响到一些正常的事件处理。

比如一些有点击热点统计工具,会统计用户在页面上各个地方的点击数。如果你在某个元素中阻止了点击事件的冒泡,那么统计工具将不能统计对应地方的点击数。

image

$$


练习

  1. 补全以下代码,使其点击颜色能显示提醒。

$$demo

<div id="blue"> <div id="green"> <div id="red"></div> </div> </div> <script> function alertColor(color) { return function () { alert(你点击的是${color}色区域。)

        event.stopPropagation()
    }
}

red.onclick = alertColor("红")
green.onclick = alertColor("绿")
blue.onclick = alertColor("蓝")

</script> <style> #red { width: 25px; height: 25px; border-radius: 50%; }

#green,
#blue {
    padding: 25px;
    border-radius: 50%;

    width: max-content;
}

#red {
    background-color: red;
}
#green {
    background-color: green;
}
#blue {
    background-color: blue;
}

</style>

$$

<div id="blue">
    <div id="green">
        <div id="red"></div>
    </div>
</div>
<script>
    // 补全 JavaScript 代码
</script>
<style>
    #red {
        width: 25px;
        height: 25px;
        border-radius: 50%;
    }

    #green,
    #blue {
        padding: 25px;
        border-radius: 50%;

        width: max-content;
    }

    #red {
        background-color: red;
    }
    #green {
        background-color: green;
    }
    #blue {
        background-color: blue;
    }
</style>

$$answer

<div id="blue">
    <div id="green">
        <div id="red"></div>
    </div>
</div>
<script>
    function alertColor(color) {
        return function (event) {
            alert(`你点击的是${color}色区域。`)

            event.stopPropagation()
        }
    }

    red.onclick = alertColor("红")
    green.onclick = alertColor("绿")
    blue.onclick = alertColor("蓝")
</script>
<style>
    #red {
        width: 25px;
        height: 25px;
        border-radius: 50%;
    }

    #green,
    #blue {
        padding: 25px;
        border-radius: 50%;

        width: max-content;
    }

    #red {
        background-color: red;
    }
    #green {
        background-color: green;
    }
    #blue {
        background-color: blue;
    }
</style>

$$