事件
在文档、浏览器、标签元素等元素在特定状态下触发的行为即为事件,比如用户的单击行为、表单内容的改变行为即为事件,我们可以为不同的事件定义处理程序。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的参数说明如下
- 参数一事件类型
- 参数二事件处理程序callback
- 参数三为定制的选项,可传递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是控制鼠标移动事件的来源和目标对象的
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 |
提交表单时触发 |