03-JS 事件

image-20251125100829463

1.事件绑定

事件组成三要素:

  • 事件源,触发谁的事件
  • 事件类型,触发什么事件
  • 事件处理函数,触发以后做什么

.addEventListener(事件类型, 事件回调函数) 添加绑定事件,可以添加多个,会按顺序执行。

语法:

1
2
3
4
// 可以添加多个
e.addEventListener("click", function(){
//事件处理代码
})

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="box">aaaaa</button>
<button id="box2">bbbbb</button>
<script>
box.onclick = function() {
console.log(111111)
}
// dom0 类型的事件,后面会覆盖前面的
box.onclick = function() {
console.log(22222)
}

// dom2 绑定多个事件处理函数,按照顺序执行
box2.addEventListener("click", function(){
console.log("3333333")
})
box2.addEventListener("click", function(){
console.log("44444444")
})
// dom2 兼容性 IE678 - 现在基本已不需要去考虑了
box2.attachEvent("onclick", function() {
console.log("11111111")
})
box2.attachEvent("onclick", function() {
console.log("22222222")
})
</script>
</body>
</html>

2.事件解绑

.removeEventListener(事件类型, 事件回调函数) 移除对应时间类型和绑定事件。

语法:

1
2
3
4
5
function handler() {
//事件处理代码
this.removeEventListener("click", handler) //事件解绑
}
btn.addEventListener("click", handler)

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn">抽奖</button>
<script>
btn.onclick = function() {
//console.log("谢谢惠顾1")
//this.disabled = "disabled" // 赋值必须是字符串
}

// dom0 事件解绑
btn.onclick = function() {
//console.log("谢谢惠顾2")
//this.onclick = null
}

// dom2 事件解绑
function handler() {
console.log("谢谢惠顾3")
this.removeEventListener("click", handler)
}
btn.addEventListener("click", handler)

// dom2 兼容性 IE678 - 现在基本已不需要去考虑了
function handler() {
console.log("谢谢惠顾IE678")
btn.detachEvent("onclick", handler)
}
btn.attachEvent("onclick", handler)
</script>
</body>
</html>

3.事件类型

常见事件:浏览器事件、鼠标事件、键盘事件、表单事件、触摸事件

更多HTML DOM 事件参考手册:https://www.w3school.com.cn/jsref/dom_obj_event.asp

3.1 浏览器事件

  • onload 页面资源全部加载完
  • onscroll 浏览器窗口滚动事件

3.2 鼠标事件

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#box{
width: 200px;
height: 200px;
background: yellow;
}
#child{
width: 100px;
height: 100px;
background: red;
}
</style>
</head>
<body>
<button id="btn">点击</button>
<button id="btn2">鼠标</button>
<div id="box">
<div id="child"></div>
</div>
<script>
/* 鼠标事件 */
// 鼠标点击
btn.onclick = function() {
console.log("鼠标单击按钮了")
}
btn.ondblclick = function() {
console.log("鼠标双击按钮了")
}
btn.oncontextmenu = function() {
console.log("鼠标右键点击按钮了")
}
// 其他事件均有页面级的对应效果
document.oncontextmenu = function() {
console.log("鼠标右键点击页面了")
}
// 鼠标按下和移动和抬起
btn2.onmousedown = function() {
console.log("鼠标按下按钮了")
}
btn2.onmousemove = function() {
console.log("鼠标在按钮上移动了")
}
btn2.onmouseup = function() {
console.log("鼠标抬起按钮了")
}
// 移入移出1 onmouseover, onmouseout : 会给子元素加上事件,子元素身上也会额外触发
// box.onmouseover = function() {
// console.log("移入")
// }
// box.onmouseout = function() {
// console.log("移出")
// }
// 移入移出2 onmouseenter, onmouseleave:只给当前元素绑定,不涉及子元素
box.onmouseenter = function() {
console.log("移入")
}
box.onmouseleave = function() {
console.log("移出")
}
</script>
</body>
</html>

3.3 键盘事件

示例:

1
2
3
4
5
6
7
8
9
10
<input type="text" id="username">
<script>
// window, document, 输入框 input
username.onkeydown = function() {
console.log("按下键盘了")
}
username.onkeyup = function() {
console.log("抬起键盘了")
}
</script>

3.4 表单事件

  • onfocus 绑input框 获取焦点
  • onblur 绑input框 失去焦点
  • onchange 绑input框 获取焦点+失去焦点+内容改变 才会触发
  • oninput 绑input框 内容不一样就触发
  • onsubmit 绑form表单 提交事件 (function中 return false 可以阻止提交事件)
  • onreset 绑from表单 重置事件
  • 更多参考:https://www.w3school.com.cn/jsref/dom_obj_event.asp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<form action="" id="myForm">
<input type="text" id="username">

<input type="submit" value="提交">
<input type="reset" value="重置">
</form>

<script>
// 焦点 focus, blur
username.onfocus = function() {
console.log("获取焦点")
}
username.onblur = function() {
console.log("失去焦点")
}
// change 获取焦点、失去焦点、内容改变 才会触发
username.onchange = function() {
console.log("获取焦点+失去焦点+内容改变了")
}
// input 内容不一样就会触发
username.oninput = function() {
console.log("内容改变了")
}
// submit, reset 只能绑定在 form 表单上上
myForm.onsubmit = function() {
console.log("表单提交!!!")
// 阻止表单提交 - 示例使用,实际根据场景使用
return false
}
myForm.onreset = function() {
console.log("表单重置!!!")
}
</script>

3.5 触摸事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
width: 100px;
height: 100px;
background: blue;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
// 移动设备仿真调试,才能触发效果
box.ontouchstart = function() {
console.log("触摸按住了")
}
box.ontouchmove = function() {
console.log("触摸移动了")
}
box.ontouchend = function() {
console.log("触摸松开了")
}
</script>
</body>
</html>

4.事件对象

4.1 事件对象

event 事件处理函数中的参数,可以拿到事件对应的对象的属性。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<input type="text" id="username">
<div id="box"></div>
<script>
username.onkeyup = function(event) {
// 键盘事件对象
// console.log(event)
console.log(event.keyCode)
// 示例:回车键 keyCode=13
if (event.keyCode === 13) {
console.log("按回车键了")
}
}

box.onclick = function(event) {
// 鼠标事件对象
// event 在IE678不支持,兼容性使用 window.event
event = event || window.event
console.log(event)
}
</script>

4.2 鼠标事件对象

  • clientXclientY 距离浏览器可视窗口左上角的坐标值
  • pageXpageY 距离页面文档流左上角的坐标值
  • offsetXoffsetY 距离【触发元素】的左上角的坐标值 (冒泡现象:点击到大盒子上的小盒子则相对于小盒子,此时小盒子是触发元素)

image-20251210121103488

image-20251210121133152

image-20251210121408559

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
width: 2000px;
height: 2000px;
}
div {
width: 200px;
height: 200px;
background: skyblue;
margin: 100px;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
box.onclick = function(evt) {
// 距离浏览器可视窗口左上角的坐标值
console.log(evt.clientX, evt.clientY)
// 距离页面文档流左上角的坐标值
console.log(evt.pageX, evt.pageY)
// 距离【触发元素】的左上角的坐标值
console.log(evt.offsetX, evt.offsetY)
}
</script>
</body>
</html>

案例:鼠标跟随

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
#box, #box2 {
width: 200px;
height: 100px;
background: yellow;
position: relative;
}
#box p{
width: 300px;
height: 200px;
background: red;
position: absolute;
left: 100px;
top: 100px;
display: none;

/* 穿透,防止鼠标移动时闪烁 */
pointer-events: none;

/* 提高鼠标跟随显示内容的层级,高一点防止被其他内容遮挡 */
z-index: 100;
}
</style>
</head>
<body>
<div id="box">
我的头像
<p>我的介绍信息:这家伙不懒,留下了一堆信息。</p>
</div>
<br>
<div id="box2">其他内容</div>

<script>
box.onmouseover = function() {
console.log("鼠标移入")
this.firstElementChild.style.display = "block"
}
box.onmouseout = function() {
console.log("鼠标移出")
this.firstElementChild.style.display = "none"
}
box.onmousemove = function(evt) {
this.firstElementChild.style.left = evt.offsetX + 10 + "px"
this.firstElementChild.style.top = evt.offsetY + 10 + "px"
}
</script>
</body>
</html>

效果:

chrome-capture-2025-12-10

案例:鼠标拖拽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}

#box {
width: 200px;
height: 100px;
background: red;
position: absolute;
}
</style>
</head>

<body>
<div id="box"></div>
<script>
var isDown = false
box.onmousedown = function () {
console.log("down")
isDown = true
}
box.onmouseup = function () {
console.log("up")
isDown = false
// document.onmousemove = null
}

// 鼠标按下的时候,鼠标移动绑定到 document 文档流上
document.onmousemove = function (evt) {
if (!isDown) return
var x = evt.offsetX - box.offsetWidth / 2
var y = evt.offsetY - box.offsetHeight / 2
if (y < 0) y = 0
if (x < 0) x = 0
if (x >= document.documentElement.clientWidth - box.offsetWidth) {
x = document.documentElement.clientWidth - box.offsetWidth
}
if (y >= document.documentElement.clientHeight - box.offsetHeight) {
y = document.documentElement.clientHeight - box.offsetHeight
}
box.style.left = x + "px"
box.style.top = y + "px"
}
</script>
</body>

</html>

效果:

chrome-capture-2025-12-10 (1)

5.DOM事件流

5.1 DOM事件流-冒泡

当元素触发一个事件的时候,其父元素也会触发相同的事件,父元素的父元素也会触发相同的事件。

如图所示:

  • 点击inner盒子的时候触发自己的事件,同理center > outer > body > html > document > window都触发对应的点击事件(跟子元素的定位位置是否在视觉上覆盖到父元素上没有关系

image-20251210125321210

image-20251210160748658

标准的DOM事件流传播的三个阶段:

  1. 捕获:window > document > html > body > outer > center > inner
  2. 目标:inner
  3. 冒泡(默认触发):inner > center > outer > body > html > document > window (IE低版本只支持冒泡触发)

按照DOM2事件绑定,并进行配置,才能看到捕获的回调函数被触发。

演示验证:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#outer{
width: 300px;
height: 300px;
background: yellow;
overflow: hidden;
}
#center{
width: 200px;
height: 200px;
background: blue;
margin: 20px;
overflow: hidden;
}
#inner{
width: 100px;
height: 100px;
background: red;
margin: 20px;
}
</style>
</head>
<body>
<div id="outer">
<div id="center">
<div id="inner">
</div>
</div>
</div>

<script>
// 点击inner时,父元素center和父的父元素outer都会触发点击事件
// inner.onclick = function() {
// console.log("inner")
// }
// center.onclick = function() {
// console.log("center")
// }
// outer.onclick = function() {
// console.log("outer")
// }
// document.body.onclick = function() {
// console.log("body")
// }
// document.documentElement.onclick = function() {
// console.log("html")
// }
// document.onclick = function() {
// console.log("document")
// }
// window.onclick = function() {
// console.log("window")
// }

// 冒泡触发:inner > center > outer > body > html > document > window
window.addEventListener("click", function() {
console.log("window")
})
document.addEventListener("click", function() {
console.log("document")
})
document.documentElement.addEventListener("click", function() {
console.log("html")
})
document.body.addEventListener("click", function() {
console.log("body")
})
outer.addEventListener("click", function() {
console.log("outer")
})
center.addEventListener("click", function() {
console.log("center")
})
inner.addEventListener("click", function() {
console.log("inner")
})

// 捕获触发:window > document > html > body > outer > center > inner
window.addEventListener("click", function() {
console.log("window-捕获")
}, true)
document.addEventListener("click", function() {
console.log("document-捕获")
}, true)
document.documentElement.addEventListener("click", function() {
console.log("html-捕获")
}, true)
document.body.addEventListener("click", function() {
console.log("body-捕获")
}, true)
outer.addEventListener("click", function() {
console.log("outer-捕获")
}, true)
center.addEventListener("click", function() {
console.log("center-捕获")
}, true)
inner.addEventListener("click", function() {
console.log("inner-捕获")
}, true)
</script>
</body>
</html>

5.2 阻止事件传播

  • evt.stopPropagation() 阻止事件传播,事件回调函数中使用。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul id="list"></ul>
<script>
var arr = ["111", "222", "333", "444"]
for (var i = 0; i < arr.length; i++) {
var oli = document.createElement("li")
oli.innerHTML = arr[i]

var obutton = document.createElement("button")
obutton.innerHTML = "删除"
obutton.onclick = handler
oli.appendChild(obutton)

// 点击删除一个li后,会跳转页面
oli.onclick = function() {
location.href = "https://www.baidu.com/"
}

list.appendChild(oli)
}

function handler (evt) {
console.log(this) // this:<button>删除</button>
//this.parentNode.remove() // this 的父节点为 li,即可删除成功
this.parentNode.parentNode.removeChild(this.parentNode) // this 的父节点为 li,即可删除成功

// 阻止事件传播(IE678低版本不兼容)
evt.stopPropagation()
// 阻止事件传播-IE兼容方式
evt.cancelBubble = true
}
</script>
</body>
</html>

效果(button是li的子元素,button上的删除节点操作会传播到li上,li的跳转也会执行。因此需要阻止事件传播。删除是删除、li元素点击也能正常跳转):

chrome-capture-2025-12-10 (2)

5.3 阻止默认行为

  • return false 事件回调函数中使用,即可阻止默认行为
  • evt.preventDefault() dom2的方式阻止默认行为,IE678兼容:evt.returnValue = false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
// dom0 的组织默认行为方式:return false 阻止默认行为
// document.oncontextmenu = function() {
// console.log("点击右键了")
// return false
// }

// dom2 的阻止默认行为方式:evt.preventDefault()
// dom2 IE678兼容: evt.returnValue = false
document.addEventListener("contextmenu", function(evt) {
console.log("点击右键了")
// return false
evt.preventDefault()
})
</script>

案例:自定义右键菜单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
ul {
list-style: none;
width: 200px;
padding: 10px;
border: 1px solid black;
display: none;
position: relative;
}
ul li:hover{
background: skyblue;
}
</style>
</head>
<body>
<ul id="list">
<li class="aaa">右键菜单111</li>
<li class="bbb">右键菜单222</li>
<li class="ccc">右键菜单333</li>
</ul>

<script>
document.addEventListener("contextmenu", function(evt) {
// 阻止掉默认右键菜单
evt.preventDefault()
list.style.display = "block"
var x = evt.clientX
var y = evt.clientY

// 防止视口右侧和底部超出
if (x >= document.documentElement.clientWidth - list.offsetWidth) {
x = document.documentElement.clientWidth - list.offsetWidth
}
if (y >= document.documentElement.clientHeight - list.offsetHeight) {
y = document.documentElement.clientHeight - list.offsetHeight
}
// -1 的操作是为了让边框展示出来,减去的是右键边框尺寸
list.style.left = x - 1 + "px"
list.style.top = y - 1 + "px"
})

// 点击其他位置,让右键消失
document.addEventListener("click", () => {
list.style.display = "none"
})

// 利用冒泡的特点,点击li时,ul会知道这个点击事件,然后一个回调中去区分处理即可
list.onclick = function() {
console.log("点击右键菜单了")
}
</script>
</body>
</html>

效果:

chrome-capture-2025-12-10 (3)

6. 事件委托

事件委托,就是把要做的事情委托给别人来做。

因为事件传播的冒泡机制,点击子元素的时候,也会同步触发父元素的相同事件,所以就可以把子元素的事件委托给父元素来做。

6.1 target 属性

  • target 属性,是事件对象里面的属性,表示你点击的目标。
    • 当触发点击事件的时候,点击在哪个元素上,target就是哪个元素
    • IE678不兼容,在IE下要使用 srcElement

用法:

1
2
3
4
5
6
7
8
9
10
11
12
<ul id="list">
<li>
11111
<button>按钮</button>
</li>
</ul>
<script>
// 按钮 冒泡到了父元素 li 以及 父的父元素 ul身上,触发了 onclick
list.onclick = function(evt) {
console.log(evt.target || evt.srcElement) // <button>按钮</button>
}
</script>

案例:自定义右键菜单改造

给ul这个父元素绑上事件,通过evt.target.className去判断和操作子元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
ul {
list-style: none;
width: 200px;
padding: 10px;
border: 1px solid black;
display: none;
position: relative;
}
ul li:hover{
background: skyblue;
}
</style>
</head>
<body>
<ul id="list">
<li class="aaa">右键菜单111</li>
<li class="bbb">右键菜单222</li>
<li class="ccc">右键菜单333</li>
</ul>

<script>
document.addEventListener("contextmenu", function(evt) {
// 阻止掉默认右键菜单
evt.preventDefault()
list.style.display = "block"
var x = evt.clientX
var y = evt.clientY

// 防止视口右侧和底部超出
if (x >= document.documentElement.clientWidth - list.offsetWidth) {
x = document.documentElement.clientWidth - list.offsetWidth
}
if (y >= document.documentElement.clientHeight - list.offsetHeight) {
y = document.documentElement.clientHeight - list.offsetHeight
}
// -1 的操作是为了让边框展示出来,减去的是右键边框尺寸
list.style.left = x - 1 + "px"
list.style.top = y - 1 + "px"
})

// 点击其他位置,让右键消失
document.addEventListener("click", () => {
list.style.display = "none"
})

// 利用冒泡的特点,点击li时,ul会知道这个点击事件,然后一个回调中去区分处理即可
// list.onclick = function() {
// console.log("点击右键菜单了")
// }

// 事件委托:evt.target 可以知道点击的是哪个元素
list.onclick = function(evt) {
console.log("点击右键菜单了")
if (evt.target.className === "aaa") {
console.log("点击了菜单aaa要做的事情")
} else if (evt.target.className === "bbb") {
console.log("点击了菜单bbb要做的事情")
} else if (evt.target.className === "ccc") {
console.log("点击了菜单ccc要做的事情")
}
}
</script>
</body>
</html>

效果是一样的。

案例:动态删除改造

给ul这个父元素绑上事件,通过evt.target.nodeType去判断和操作子元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul id="list"></ul>
<script>
var arr = ["111", "222", "333", "444"]
for (var i = 0; i < arr.length; i++) {
var oli = document.createElement("li")
oli.innerHTML = arr[i]

var obutton = document.createElement("button")
obutton.innerHTML = "删除"
//obutton.onclick = handler
oli.appendChild(obutton)
list.appendChild(oli)
}

//function handler () {
//console.log(this) // this:<button>删除</button>
//this.parentNode.remove() // this 的父节点为 li,即可删除成功
//}

// 给ul这个父元素绑上事件,通过evt的target去判断和操作子元素
list.onclick = function(evt) {
console.log(evt.target)
if (evt.target.nodeName === "BUTTON") {
evt.target.parentNode.remove()
}
}
</script>
</body>
</html>

效果是一样的动态删除li。


03-JS 事件
https://janycode.github.io/2018/04/28/04_大前端/03_JavaScript/03-JS 事件/
作者
Jerry(姜源)
发布于
2018年4月28日
许可协议