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

常用事件

常用的事件有以下这些:

鼠标事件:

鼠标事件的事件类型统一为 MouseEvent

键盘事件:

键盘事件的事件类型统一为 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>

$$

DOM 属性

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

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

$$demo

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

$$

清除绑定

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

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

$$demo

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

$$

addEventListener

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

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

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

$$demo

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

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

</script>

$$

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

addEventListener 的语法如下:

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

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

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

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

$$demo

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

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

</script>

$$

清除绑定

removeEventListener 的语法很是相似:

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

$$tip

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

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

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

$$

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

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

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

$$demo

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

btn.addEventListener("click", greet)
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)
    }

    btn.onclick = greet
    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) }

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

</script>

$$

事件对象

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

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

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

    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 }

btn.onclick = greet

</script>

$$


练习

  1. 实现以下的实例效果,当输入超过 5 个字符后输入框变红且显示提示语。 $$demo <input class="username" type="text" placeholder="请输入用户名" /> <span class="prompt" hidden>最多输入 5 个字符。</span> <script> document.querySelector(".username").oninput = function (event) { if (event.target.value.length > 5) { event.target.classList.add("warning") document.querySelector(".prompt").hidden = false } else { event.target.classList.remove("warning") document.querySelector(".prompt").hidden = true } } </script> <style> .username { padding: 10px;

     border: none;
    
     outline: 2px #999 solid;
    
     border-radius: 4px;
    

    }

    .warning { outline: 2px red solid; } </style> $$ $$answer

$$jsdemo$$
$$edit$$
<input class="username" type="text" placeholder="请输入用户名" />
<span class="prompt" hidden>最多输入 5 个字符。</span>
<script>
    document.querySelector(".username").oninput = function (event) {
        if (event.target.value.length > 5) {
            event.target.classList.add("warning")
            document.querySelector(".prompt").hidden = false
        } else {
            event.target.classList.remove("warning")
            document.querySelector(".prompt").hidden = true
        }
    }
</script>
<style>
    .username {
        padding: 10px;

        border: none;

        outline: 2px #999 solid;

        border-radius: 4px;
    }

    .warning {
        outline: 2px red solid;
    }
</style>

$$

  1. 完成以下的实例,点击页面移动球。 $$tip 使用事件对象中的 clientX / clientY 获取鼠标位于页面上的坐标。 $$ $$demo <div class="ball"></div> <script> window.addEventListener("click", function (event) { console.log(event) document.querySelector(".ball").style.left = event.clientX - 50 document.querySelector(".ball").style.top = event.clientY - 50 }) </script> <style> body { min-height: 400px; } .ball { width: 100px; height: 100px; border-radius: 50%;

     background-color: teal;
    
     position: fixed;
     top: 0;
     left: 0;
    

    } </style> $$ $$answer

<div class="ball"></div>
<script>
    window.addEventListener("click", function (event) {
        console.log(event)
        document.querySelector(".ball").style.left = event.clientX - 50
        document.querySelector(".ball").style.top = event.clientY - 50
    })
</script>
<style>
    .ball {
        width: 100px;
        height: 100px;
        border-radius: 50%;

        background-color: teal;

        position: fixed;
        top: 0;
        left: 0;
    }
</style>

$$