JavaScript 基础
Document
运算符
深入数据和类型
函数进阶
原型、继承
类
浏览器存储
Web API
事件
错误处理
异步编程
网络请求
模块
练习
实例
工具与规范
软件架构模式
设计模式
事件是能够响应用户操作或某个阶段(例如页面载入、视频暂停等)而不可或缺的一个机制。
常用事件
常用的事件有以下这些:
鼠标事件:
- click:鼠标点击事件。
- contextmenu:鼠标右击事件。
- mouseover:鼠标移入元素事件。
- mouseout:鼠标离开元素事件。
- mousedown:鼠标在元素上按下的事件。
- mouseup:鼠标在元素上释放的事件。
- mosemove:鼠标移动时。
键盘事件:
键盘事件的事件类型统一为 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 属性绑定事件,因为容易造成 this
和 event
不明确。
$$
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:添加一个事件处理函数。
- removeEventListener:移除一个事件处理函数。
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>
$$
练习
-
补全代码,使用三种方式绑定事件。 $$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>
$$