0%

事件

在文档、浏览器、标签元素等元素在特定状态下触发的行为即为事件,比如用户的单击行为、表单内容的改变行为即为事件,我们可以为不同的事件定义处理程序。JS使用异步事件驱动的形式管理事件。

事件类型

JS为不同的事件定义的类型,也可以称为事件名称。

事件目标

事件目标指触发事件的对象,比如a标签被点击那么a标签就是事件目标。元素是可以嵌套的,所以在进行一次点击行为时可能会触发多个事件目标(事件冒泡)。

处理程序

事件的目的是要执行一段代码,我们称这类代码块为事件处理(监听)程序。当在对象上触发事件时就会执行定义的事件处理程序。

HTML绑定

可以在html元素上设置事件处理程序,浏览器解析后会绑定到DOM属性中

1
<button onclick="alert(`Ashuntefannao`)">阿顺特烦恼</button>

往往事件处理程序业务比较复杂,所以绑定方法或函数会很常见

  • 绑定函数或方法时需要加上括号
1
2
3
4
5
6
<button onclick="show()">阿顺特烦恼</button>
<script>
function show() {
alert('Ashuntefannao')
}
</script>

当然也可以使用对象方法做为事件处理程序

1
2
3
4
5
6
7
8
<input type="text" onkeyup="SHUN.show()" />
<script>
class SHUN {
static show() {
console.log('Ashun')
}
}
</script>

可以传递事件源对象与事件对象

  • 传入this指向事件源span元素
  • 传入event指向事件对象,可通过其访问各种事件处理的属性/方法。
1
2
3
4
5
6
7
<!-- this指向span元素,event为事件对象,-->
<span onclick="show(this,'Ashun','阿顺特烦恼',event)">ASHUN</span>
<script>
function show(...args) {
console.log(args)
}
</script>

DOM绑定

也可以将事件处理程序绑定到DOM属性中

  • 使用setAttribute方法设置事件处理程序无效
  • 属性名区分大小写
1
2
3
4
5
6
7
<div id="app">Ashuntefannao/div>
<script>
const app = document.querySelector('#app')
app.onclick = function () {
this.style.color = 'red'
}
</script>

无法为事件类型绑定多个事件处理程序,下面绑定了多个事件处理程序,因为属性是相同的所以只有最后一个有效

1
2
3
4
5
6
7
8
9
10
<div id="app">Ashuntefannao</div>
<script>
const app = document.querySelector('#app')
app.onclick = function () {
this.style.color = 'red'
}
app.onclick = function () {
this.style.fontSize = '55px'
}
</script>

事件监听

通过上面的说明我们知道使用HTML与DOM绑定事件都有缺陷,建议使用新的事件监听绑定方式addEventListener 操作事件

使用addEventListener添加事件处理程序有以下几个特点

  • transtionend / DOMContentLoaded 等事件类型只能使用 addEventListener 处理
  • 同一事件类型可以设置多个事件处理程序,按设置的顺序先后执行
  • 也可以对未来添加的元素绑定事件
方法 说明
addEventListener 添加事件处理程序
removeEventListener 移除事件处理程序

addEventListener的参数说明如下

  1. 参数一事件类型
  2. 参数二事件处理程序callback
    • callback默认接收event事件对象参数
  3. 参数三为定制的选项,可传递object或boolean类型。后面会详细介绍使用区别

绑定多个事件

使用addEventListener来多个事件处理程序

1
2
3
4
5
6
7
8
9
10
<div id="app">Ashuntefannao</div>
<script>
const app = document.querySelector('#app')
app.addEventListener('click', function () {
this.style.color = 'red'
})
app.addEventListener('click', function () {
this.style.fontSize = '55px'
})
</script>

通过对象绑定

事件处理程序可以是对象,对象的 handleEvent 方法会做为事件处理程序执行。下面将元素的事件统一交由对象处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="app">Ashuntefannao</div>
<script>
const app = document.querySelector('#app')
class Events {
handleEvent(e) {
this[e.type](e)
}
click() {
console.log('单击事件')
}
mouseover() {
console.log('鼠标悬停事件')
}
}
app.addEventListener('click', new Events())
app.addEventListener('mouseover', new Events())
</script>

移除事件

使用removeEventListener删除事先绑定的事件处理函数

  • 事件处理程序单独定义函数或方法,这可以保证访问的事件处理程序是同一个
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div id="app">Ashuntefannao</div>
<button id="rmEvent">删除事件</button>

<script>
const app = document.querySelector('#app')
const rm = document.querySelector('#rmEvent')
function show(event) {
console.log(event.target)
console.log('APP我执行了')
}
app.addEventListener('click', show)
rm.addEventListener('click', function () {
app.removeEventListener('click', show)
})
</script>

事件选项

addEventListener的第三个参数为定制的选项,可传递object或boolean类型

下面是传递对象时的说明

选项 可选参数
once true/false 只执行一次事件
capture true/false 事件是在捕获/冒泡哪个阶段执行,true:捕获阶段 false:冒泡阶段,默认为false
passive true/false 声明事件里不会判断 preventDefault(),可以减少系统默认行为的等待

传递Boolean时

  • true:事件捕获方式执行,等同于参数{capture:true}
  • false:事件冒泡方式执行,等同于参数{capture:false}

事件捕获

事件执行顺序:最顶层window->最底层触发事件的dom

事件冒泡

事件执行顺序与事件捕获相反

下面使用once:true 来指定事件只执行一次

1
2
3
4
5
6
7
8
9
10
11
<button id="app">Ashuntefannao</button>
<script>
const app = document.querySelector('#app')
app.addEventListener(
'click',
function () {
alert('阿顺特烦恼_Ashun')
},
{ once: true }
)
</script>

设置 { capture: true } 或直接设置第三个参数为true用来在捕获阶段执行事件

addEventListener的第三个参数传递true/false 和设置 {capture:true/false}是一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app" style="background-color: red">
<button id="bt">Ashuntefannao</button>
</div>
<script>
const app = document.querySelector('#app')
const bt = document.querySelector('#bt')
app.addEventListener(
'click',
function () {
alert('这是div事件 ')
},
{ capture: true }
)

bt.addEventListener(
'click',
function () {
alert('这是按钮事件 ')
},
{ capture: true }
)
</script>

设置 { capture: false } 或 直接设置第三个参数为false 或 不设置第三个参数(默认为false), 用来在冒泡阶段执行事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app" style="background-color: red">
<button id="bt">Ashuntefannao</button>
</div>
<script>
const app = document.querySelector('#app')
const bt = document.querySelector('#bt')
app.addEventListener(
'click',
function () {
alert('这是div事件 ')
},
{ capture: false }
)

bt.addEventListener(
'click',
function () {
alert('这是按钮事件 ')
},
{ capture: false }
)
</script>

passive选项: 声明事件里不会判断 preventDefault(),可以减少系统默认行为的等待

很多移动端的页面都会监听 touchstart 等 touch 事件,像这样:

1
2
3
document.addEventListener("touchstart", function(e){
... // 浏览器不知道这里会不会有 e.preventDefault()
})

由于 touchstart 事件对象的 cancelable 属性为 true,也就是说它的默认行为可以被监听器通过 preventDefault() 方法阻止,那它的默认行为是什么呢,通常来说就是滚动当前页面(还可能是缩放页面),如果它的默认行为被阻止了,页面就必须静止不动。但浏览器无法预先知道一个监听器会不会调用 preventDefault(),它能做的只有等监听器执行完后再去执行默认行为,而监听器执行是要耗时的,有些甚至耗时很明显,这样就会导致页面卡顿。即便监听器是个空函数,也会产生一定的卡顿,毕竟空函数的执行也会耗时。

事件对象

执行事件处理程序时,会产生包含当前事件相关信息的对象,即为事件对象。系统会自动做为参数传递给事件处理程序

  • 大部分浏览器将事件对象保存到window.event中
  • 有些浏览器会将事件对象做为事件处理程序的参数传递

事件对象常用属性如下:

属性 说明
type 事件类型
target 事件目标对象,冒泡方式时父级对象可以通过该属性找到在哪个子元素上最终执行事件
currentTarget 当前执行事件的对象
timeStamp 事件发生时间
x 相对窗口的X坐标
y 相对窗口的Y坐标
clientX 相对窗口的X坐标
clientY 相对窗口的Y坐标
screenX 相对计算机屏幕的X坐标
screenY 相对计算机屏幕的Y坐标
pageX 相对于文档的X坐标
pageY 相对于文档的Y坐标
offsetX 相对于事件对象的X坐标
offsetY 相对于事件对象的Y坐标
layerX 相对于父级定位的X坐标
layerY 相对于父级定位的Y坐标
path 冒泡的路径
altKey 是否按了alt键
shiftKey 是否按了shift键
metaKey 是否按了媒体键
window.pageXOffset 文档参考窗口水平滚动的距离
window.pageYOffset 文档参考窗口垂直滚动的距离

冒泡捕获

冒泡行为

事件默认是冒泡执行的:标签元素是嵌套的,在一个元素上触发的事件,同时也会向上触发父级元素对应的事件处理程序,一直到最顶层window。

  • 大部分事件都会冒泡,但像focus事件则不会
  • event.target 指向事件链中最底层事件的对象
  • event.currentTarget == this 即当前执行事件的对象

以下示例有标签的嵌套,并且父子标签都设置了事件,当在子标签上触发事件事会冒泡执行父级标签的事件,直至window

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
<style>
#app {
height: 70px;
background-color: #95a5a6;
}
strong {
display: block;
height: 30px;
background-color: #f39c12;
}
</style>
<body>
<div id="app">
Ashuntefannao
<strong>MyStrong</strong>
</div>
</body>
<script>
const app = document.querySelector("#app");
const strong = document.querySelector("strong");

window.addEventListener("click", () => {
console.log("window Method");
});
document.documentElement.addEventListener("click", () => {
console.log("html Method");
});
app.addEventListener("click", () => {
console.log("App Method");
});
strong.addEventListener("click", () => {
console.log("strong Method");
});
</script>

下例无论点击哪个元素,都会变为蓝色

  • event.target指向事件链中的最底层的事件对象
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
<style>
body {
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}

article {
width: 200px;
height: 200px;
display: flex;
justify-content: center;
align-items: center;
background: #5f27cd;
border-radius: 10px;
}

section {
width: 100px;
height: 100px;
background: #ff9f43;
border-radius: 5px;
}
</style>
<body>
<article>
<section></section>
</article>
</body>
<script>
document.body.addEventListener("click", (evnet) => {
event.target.style.background = "#0abde3"; // 祖先级body改蓝色
console.log(event.target); //由于冒泡执行,点击任意元素,该语句都会执行
});

document.querySelector("article").addEventListener("click", (event) => {
event.target.style.background = "#ee5253"; // 父级article改红色
});

document.querySelector("section").addEventListener("click", (event) => {
event.target.style.background = "#10ac84"; // 子级section改绿色
});
</script>

若通过event.currentTarget处理当前所触发事件的元素,则更改的颜色就会对应起来

  • 由于事件冒泡,点击某个元素,也会导致其祖先元素的更改
1
2
3
4
5
6
7
8
9
10
11
12
……
document.body.addEventListener("click", (evnet) => {
event.currentTarget.style.background = "#0abde3"; // 祖先级body改蓝色
});

document.querySelector("article").addEventListener("click", (event) => {
event.currentTarget.style.background = "#ee5253"; // 父级article改红色
});

document.querySelector("section").addEventListener("click", (event) => {
event.currentTarget.style.background = "#10ac84"; // 子级section改绿色
});

阻止冒泡

冒泡过程中的任何事件处理程序中,都可以执行 event.stopPropagation/stopImmediatePropagation() 方法阻止继续进行冒泡传递

  • event.stopPropagation() 用于阻止冒泡
  • event.stopImmediatePropagation() 阻止事件冒泡并且阻止相同事件类型的其他事件处理函数被调用

使用event.stopPropagation处理冒泡行为中的例子,通过阻止冒泡,点击某个元素,不会影响祖先元素的背景颜色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
……
document.body.addEventListener("click", (evnet) => {
event.currentTarget.style.background = "#0abde3";
console.log(event.target);
});

document.querySelector("article").addEventListener("click", (event) => {
event.stopPropagation();
event.currentTarget.style.background = "#ee5253";
console.log(event.currentTarget);
});

document.querySelector("section").addEventListener("click", (event) => {
event.stopPropagation();
event.currentTarget.style.background = "#10ac84";
});

stopPropagation只是阻止冒泡,不会阻止相同事件类型的其它事件处理函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</body>
<div id="app">
Ashuntefannao
<strong>MyStrong</strong>
</div>
</body>
const app = document.querySelector("#app");
const strong = document.querySelector("strong");

app.addEventListener("click", () => {
console.log("App Method");
});
strong.addEventListener("click", (e) => {
e.stopPropagation();
console.log("strong Method__1");
});
strong.addEventListener("click", () => {
console.log("strong Method__2");
});

点击strong,打印结果

1
2
//strong Method__1
//strong Method__2

若将上述代码中的stopPropagation改为stopImmediatePropagation,则也会阻止相同事件的其它处理函数

1
点击strong,打印结果: //strong Method__1

事件捕获

事件捕获:事件执行顺序与冒泡行为相反,会由事件链的最顶层window逐步向下传递执行。事件捕获在实际使用中频率不高。

  • 通过设置第三个参数为true或{ capture: true } 在捕获阶段执行事件处理程序

    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
    <style>
    #app {
    height: 70px;
    background-color: #95a5a6;
    }
    strong {
    display: block;
    height: 30px;
    background-color: #f39c12;
    }
    </style>
    <body>
    <div id="app">
    Ashuntefannao
    <strong>MyStrong</strong>
    </div>
    </body>
    <script>
    const app = document.querySelector("#app");
    const strong = document.querySelector("strong");

    app.addEventListener(
    "click",
    () => {
    console.log("App Method");
    },
    true
    );

    strong.addEventListener("click", (e) => {
    console.log("strong Method__1");
    });
    strong.addEventListener("click", () => {
    console.log("strong Method__2");
    });
    </script>

    由于在给#app添加事件时,第三个参数设置为true/{capture:true},在事件捕获阶段执行,所以在点击strong时,会先执行#app的事件处理程序

    1
    2
    3
    4
    # 结果
    App Method
    strong Method__1
    strong Method__2

事件代理

借助冒泡思路,我们可以不为子元素设置事件,而将事件设置在父级。然后通过父级事件对象的event.target查找事件链底层的元素,并对它做出处理。

  • 这在为多个元素添加相同事件时很方便
  • 会使添加事件变得非常容易

下面是为父级UL设置事件来控制子元素LI的样式切换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<style>
.active {
border-radius: 10px;
background-color: #eee;
text-align: center;
}
</style>
<body>
<ul>
<li>阿顺</li>
<li>Ashuntefannao</li>
</ul>
</body>

<script>
document.querySelector("ul").addEventListener("click", (e) => {
e.target.classList.toggle("active");
});
</script>

可以使用事件代理来共享事件处理程序,不用为每个元素单独绑定事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  <ul>
<li data-action="border" data-border="2px solid #aaa">阿顺</li>
<li data-action="color" data-color="red">Ashuntefannao</li>
</ul>
<script>
class Event {
constructor(el) {
el.addEventListener("click", (e) => {
let action = e.target.dataset.action;
this[action](e.target);
});
}
border(event) {
event.style.border = event.dataset.border;
}
color(event) {
console.log(event.dataset);
event.style.color = event.dataset.color;
}
}
new Event(document.querySelector("ul"));
</script>

下面是使用事件代理实现的TAB面板效果

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
<style>
.tab {
width: 200px;
}
dl {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
dt,
dd {
width: 100%;
color: white;
}
dt {
height: 30px;
background-color: #34495e;
}
dd {
margin: 0;
padding: 0;
height: 60px;
background-color: #e67e22;
}
</style>
<body>
<div class="tab">
<dl>
<dt data-action="toggle">阿顺特烦恼</dt>
<dd data-action="hidden">Ashuntefannao</dd>
<dt data-action="toggle">阿顺</dt>
<dd data-action="hidden">Ashun</dd>
</dl>
</div>
</body>
<script>
class Card {
constructor(el) {
el.addEventListener("click", (e) => {
let action = e.target.dataset.action;
this[action](e);
});
}
toggle(event) {
event.target
.querySelectorAll("[data-action='hidden']")
.forEach((elem) => (elem.hidden = true));
event.target.nextElementSibling.hidden = false;
}
hidden(event) {
event.target.hidden = true;
}
}
new Card(document.querySelector(".tab"));
</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
<form>
<input type="text" />
<button type="button" data-submit-disabled data-action="submit,counter">提交表单</button>
</form>
<script>
class FORM {
constructor(el) {
this.$el = el;
this.sum = 0;
el.addEventListener("click", (e) => {
let actions = e.target.dataset.action;
actions &&
actions.split(",").forEach((method) => {
this[method](e);
});
});
}
submit(e) {
this.disabled(e, true);
console.log("正在提交");

setTimeout(() => {
console.log("提交成功!");
this.disabled(e, false);
}, 1000);
}
disabled(event, boolean) {
this.$el
.querySelectorAll("[data-submit-disabled]")
.forEach((btn) => (btn.disabled = boolean));
}
counter() {
console.log(`提交次数:${++this.sum}`);
}
}
new FORM(document.querySelector("form"));
</script>

未来元素

下面使用事件代理来对未来元素进行事件绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="app">

</div>

<script>
function show() {
console.log(this.textContent)
}
const app = document.querySelector('#app')
app.addEventListener('click', () => {
show.call(event.target)
})
let newH2 = document.createElement('h2')
newH2.textContent = 'Ashuntefannao'
app.append(newH2)
</script>

我们可以将这个功能封装起来,用来代理某一类未来元素的事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div id="app">
<section>My name is Section</section>
</div>

<script>
Element.prototype.on = function (EventType, Element, func) {
this.addEventListener(EventType, (event) => {
if (event.target.tagName === Element.toUpperCase()) {
func(event);
}
});
};

let app = document.querySelector("#app");

app.on("click", "h2", (event) => {
console.log(event.target);
});

let h2 = document.createElement("h2");
h2.innerText = "Ashuntefannao";
app.append(h2);
</script>

默认行为

JS中有些对象会设置默认事件处理程序,比如A链接在点击时会进行跳转,点击submit会提交表单信息…

一般默认处理程序会在用户定义的处理程序后执行,我们可以在事件处理函数中取消默认事件的执行。

  • 使用onclick绑定的事件处理程序,return false 可以阻止默认行为
  • 推荐使用event.preventDefault()阻止默认行为

下面阻止超链接的默认行为

1
2
3
4
5
6
7
<a href="https://www.baidu.com">百度一下,你就知道</a>
<script>
document.querySelector('a').addEventListener('click', () => {
event.preventDefault()
alert(event.target.innerText)
})
</script>

文档事件

下面来学习针对文档事件的处理。

事件类型

事件名 说明
window.onload 文档解析及外部资源加载后
DOMContentLoaded 文档解析后执行,不需要等待图片/样式文件等外部资源加载,该事件只能通过addEventListener设置
window.onbeforeunload 文档刷新或关闭时
window.onunload 文档卸载时
scroll 页面滚动时

onload

window.onload事件在文档解析后及图片、外部样式文件等资源加载完后执行

1
2
3
4
5
6
<script>
window.onload = function () {
alert('阿顺特烦恼')
}
</script>
<div id="app">Ashuntefannao</div>

DOMContentLoaded

DOMContentLoaded事件在文档标签解析后执行,不需要等外部图片、样式文件、JS文件等资源加载

  • 该事件只能够通过addEventListener添加
1
2
3
4
5
6
<script>
window.addEventListener('DOMContentLoaded', (event) => {
alert('阿顺特烦恼')
})
</script>
<div id="app">Ashuntefannao</div>

onbeforeunload

当浏览器窗口关闭或者刷新时,会触发beforeunload事件,可以取消关闭或刷新页面。

  • 返回值为非空字符串时,有些浏览器会做为弹出的提示信息内容
  • 部分浏览器使用addEventListener无法绑定事件
1
2
3
window.onbeforeunload = function (e) {
return '真的要离开吗?'
}

unload

window.unload事件在文档资源被卸载时执行,在beforeunload后执行

  • 不能执行alert、confirm等交互指令
  • 发生错误也不会阻止页面关闭或刷新
1
2
3
4
//文档被关闭时,在localStorage中存储用户信息
window.addEventListener('unload', function (e) {
localStorage.setItem('name', 'Ashun')
})

鼠标事件

事件类型

针对鼠标操作的行为有多种事件类型

  • 鼠标事件会触发在Z-INDEX 层级最高的那个元素上
事件名 说明
click 鼠标单击事件,同时触发 mousedown/mouseup
dblclick 鼠标双击事件
contextmenu 点击右键后显示的所在环境的菜单
mousedown 鼠标按下
mouseup 鼠标抬起时
mousemove 鼠标移动时
mouseover 鼠标移动时
mouseout 鼠标从元素上离开时
mouseup 鼠标抬起时
mouseenter 鼠标移入时触发,不产生冒泡行为
mosueleave 鼠标移出时触发,不产生冒泡行为
oncopy 复制内容时触发
scroll 元素滚动时,可以为元素设置overflow:auto; 产生滚动条来测试

禁止复制

1
2
3
4
document.addEventListener('copy', () => {
event.preventDefault()
alert('禁止复制内容')
})

relatedTarget

relatedTarget是控制鼠标移动事件的来源和目标对象的

  • 如果移动过快会跳转中间对象
1
2
3
4
5
6
7
8
9
10
<div id="app">Ashuntefannao</div>
<div id="shun">SHUN</div>
<script>
const app = document.querySelector(`#app`)
const shun = document.querySelector(`#shun`)
app.addEventListener('mouseout', () => {
console.log(event.target)
console.log(event.relatedTarget)
})
</script>

mouseenter与mouseleave

mouseenter与mouseleave事件从子元素移动到父元素时不触发父元素事件

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
<style>
#app {
background: #e74c3c;
padding: 80px;
width: 500px;
}
#shun {
background: #f39c12;
padding: 30px;
}
</style>
<div id="app">
Ashuntefannao
<div id="shun">SHUN</div>
</div>

<script>
const app = document.querySelector(`#app`)
const shun = document.querySelector(`#shun`)

app.addEventListener('mouseenter', () => {
console.log('app')
})
shun.addEventListener('mouseenter', () => {
console.log('shun')
})
</script>

键盘事件

针对键盘输入操作的行为有多种事件类型

事件名 说明
Keydown 键盘按下时,一直按键不松开时keydown事件会重复触发
keyup 按键抬起时
keypress 按键 按下、抬起 都会触发,一直按键不松开也会持续触发

事件对象

键盘事件产生的事件对象包含相对应的属性

属性 说明
keyCode 返回键盘的ASCII字符数字
code 按键码,字符以Key开始,数字以Digit开始,特殊字符有专属名子。左右ALT键字符不同。 不同布局的键盘值会不同
key 按键的字符含义表示,大小写不同。不能区分左右ALT等。不同语言操作系统下值会不同
altKey 是否按了alt键
ctrlKey 是否按了ctlr键
shiftKey 是否按了shift键
metaKey 是否按了媒体键

表单事件

下面是可以用在表单上的事件类型

事件类型 说明
focus 获取焦点事件
blur 失去焦点事件
element.focus() 让元素强制获取焦点
element.blur() 让元素失去焦点
change 文本框在内容发生改变失去焦点时触发
input value 被修改时,会触发 input 事件
submit 提交表单时触发