事件是能够响应用户操作或某个阶段(例如页面载入、视频暂停等)而不可或缺的一个机制。

常用事件

常用的事件有以下这些:

鼠标事件:

键盘事件:

键盘事件的事件类型统一为 KeyboardEvent

Window 事件:

事件类型为 Event

  • load:页面加载完成。

绑定事件

我们必须将我们的函数绑定到事件上,才能让事件在触发时执行你的代码。

绑定事件则有以下三种方法。

HTML 属性

在写一个 HTML 元素时, 就可以通过 on<event> 的属性给其绑定一段代码,这段代码将在事件触发时执行。

$$edit$$
<button onclick="alert('你好')">问候</button>

$$demo

<button onclick="alert('你好')">问候</button>

$$

在代码很多时直接写在属性中也不现实,也可以事先声明一个函数,然后在属性中调用。

$$edit$$
<button onclick="greet()">问候</button>
<script>
    function greet() {
        alert("你好")
        alert("我好")
        alert("大家好")
    }
</script>

$$demo

<button onclick="greet()">问候</button> <script> function greet() { alert("你好") alert("我好") alert("大家好") } </script>

$$

$$tip 不推荐使用 HTML 属性绑定事件,因为容易造成 thisevent 不明确。 $$

DOM 属性

我们也可以在 JavaScript 代码中通过 DOM 属性来绑定一个事件函数。

$$edit$$
<button id="btn">问候</button>
<script>
    document.getElementById("btn").onclick = function () {
        alert("你好")
        alert("我好")
        alert("大家好")
    }
</script>

$$demo

<button id="btn">问候</button> <script> document.getElementById("btn").onclick = function () { alert("你好") alert("我好") alert("大家好") } </script>

$$

清除绑定事件

不管是清除 HTML 属性还是 DOM 属性上的绑定,只需要将 DOM 属性上的 onclick 赋值为 null 或 undefined 即可。

$$edit$$
<button id="btn" onclick="alert(`你好`)">问候</button>
<script>
    // 清除绑定
    document.getElementById("btn").onclick = null
</script>

$$demo <button id="btn" onclick="alert(你好)">问候</button> <script> // 清除绑定 document.getElementById("btn").onclick = null </script> $$

addEventListener 方法

以上方法一次只能绑定一个函数,当我们有多个函数的绑定需求时就比较麻烦了。如果赋值多个函数,那么后面的函数会覆盖之前的。

$$edit$$
<button id="btn">问候</button>
<script>
    document.getElementById("btn").onclick = function () {
        // 这个被覆盖
        alert("你好")
    }

    document.getElementById("btn").onclick = function () {
        // 这个会执行
        alert("大家好")
    }
</script>

$$demo

<button id="btn">问候</button> <script> document.getElementById("btn").onclick = function () { // 这个被覆盖 alert("你好") }

document.getElementById("btn").onclick = function () {
    // 这个会执行
    alert("大家好")
}

</script>

$$

而有两个方法可以处理这个问题:

addEventListener 的语法如下:

target.addEventListener(type, listener[, options])
  • type:要绑定的事件类型。
  • listener:处理函数。
  • options:较少用到,详情可看 MDN 的文档。

以下代码中我们绑定了两个函数,都可以被执行。

$$edit$$
<button id="btn">问候</button>
<script>
    document.getElementById("btn").addEventListener("click", () => {
        alert("你好")
    })

    document.getElementById("btn").addEventListener("click", () => {
        alert("大家好")
    })
</script>

$$demo

<button id="btn">问候</button> <script> document.getElementById("btn").addEventListener("click", () => { alert("你好") })

document.getElementById("btn").addEventListener("click", () => {
    alert("大家好")
})

</script>

$$

清除绑定事件

removeEventListener 的语法很是相似:

target.removeEventListener(type, listener[, options])
  • type:要清除的事件类型。
  • listener:要清除的函数。
  • options:较少用到,详情可看 MDN 的文档。

$$tip

清除的函数必须是同一个对象,不然不起作用。

$$edit$$
<button id="btn">问候</button>
<script>
    document.getElementById("btn").addEventListener("click", () => {
        alert("你好")
    })

    // 不起作用
    document.getElementById("btn").removeEventListener("click", () => {
        alert("你好")
    })
</script>

$$

正确写法应该像下面一样, 绑定与清除都是同一个函数对象:

$$edit$$
<button id="btn">问候</button>
<script>
    function greet() {
        alert("你好")
    }

    document.getElementById("btn").addEventListener("click", greet)
    document.getElementById("btn").removeEventListener("click", greet)
</script>

$$demo

<button id="btn">问候</button> <script> function greet() { alert("你好") }

document.getElementById("btn").addEventListener("click", greet)
document.getElementById("btn").removeEventListener("click", greet)

</script>

$$

this 指向

在事件绑定的处理代码中, this 指向的是绑定事件的元素

$$edit$$
<!-- 以下按钮提示的都是自身的文本内容,说明 this 指向的是自身 -->
<button onclick="alert(this.textContent)">HTML 属性绑定</button>
<button id="btn">DOM 属性绑定</button>
<button id="btn2">addEventListener 绑定</button>
<script>
    function greet() {
        alert(this.textContent)
    }

    document.getElementById("btn").onclick = greet
    document.getElementById("btn2").addEventListener("click", greet)
</script>

$$demo

<button onclick="alert(this.textContent)">HTML 属性绑定</button> <button id="btn">DOM 属性绑定</button> <button id="btn2">addEventListener 绑定</button> <script> function greet() { alert(this.textContent) }

document.getElementById("btn").onclick = greet
document.getElementById("btn2").addEventListener("click", greet)

</script>

$$

$$warning 必须是普通函数 this 才会指向绑定事件的元素,而不能是箭头函数。 $$

$$warning 如果用 HTML 绑定事件的方法,那么只有在 HTML 代码部分的 this 指向当前元素,如果调用函数的话,函数中的 this 是不指向当前元素的。

$$

<button onclick="greet()">HTML 属性绑定</button>
<script>
    function greet() {
        alert(this) // window
    }
</script>

$$demo <button onclick="greet()">HTML 属性绑定</button> <script> function greet() { alert(this) // window } </script> $$

事件对象

在事件触发时, 浏览器会创建一个 event 对象将其作为参数传递给绑定的函数。

不同事件接收的事件类型可能会有所不同,但所有事件都继承自 Event 对象,所以 Event 对象中的属性与方法是所有对象共有的。

事件中有两个指向元素的属性:

  • target:指向触发事件的对象。
  • currentTarget:指向绑定事件的对象。
$$edit$$
<button id="btn">问候</button>
<script>
    function greet(event) {
        console.log(`事件名:${event.type}`) // click
        console.log(event.currentTarget) // 事件绑定的元素
        console.log(event.currentTarget === this) // true
    }

    document.getElementById("btn").onclick = greet
</script>

$$demo

<button id="btn">问候</button> <script> function greet(event) { console.log(事件名:${event.type}) // click console.log(event.currentTarget) // 事件绑定的元素 console.log(event.currentTarget === this) // true }

document.getElementById("btn").onclick = greet

</script>

$$

$$warning 如果用 HTML 绑定事件的方法,调用函数时别忘了传递 event 参数。 $$

<button onclick="greet(event)">HTML 属性绑定</button>
<script>
    function greet(event) {
        alert(event.currentTarget.textContent)
    }
</script>

$$demo <button onclick="greet(event)">HTML 属性绑定</button> <script> function greet(event) { alert(event.currentTarget.textContent) } </script>

$$


练习

  1. 补全代码,使用三种方式绑定事件。 $$tip 使用 bind 方法可以指定一个函数的 this 指向。 $$ $$demo <button onclick="clickAction.bind(this)(event)">在 HTML 中绑定</button> <button id="btn1">用 DOM 属性绑定</button> <button id="btn2">用 addEventListener 绑定</button> <script> function clickAction(event) { alert(event.target.textContent) alert(this.textContent) }

    document.getElementById("btn1").onclick = clickAction

    document.getElementById("btn2").addEventListener("click", clickAction) </script>

$$

<!-- 补全代码,使用三种方式绑定事件。 -->
<button>在 HTML 中绑定</button>
<button>用 DOM 属性绑定</button>
<button>用 addEventListener 绑定</button>
<script>
    function clickAction(event) {
        alert(event.currentTarget.textContent)
        alert(this.textContent)
    }
</script>

$$answer

<button onclick="clickAction.bind(this)(event)">在 HTML 中绑定</button>
<button id="btn1">用 DOM 属性绑定</button>
<button id="btn2">用 addEventListener 绑定</button>
<script>
    function clickAction(event) {
        alert(event.currentTarget.textContent)
        alert(this.textContent)
    }

    document.getElementById("btn1").onclick = clickAction

    document.getElementById("btn2").addEventListener("click", clickAction)
</script>

$$