在文档、浏览器、标签元素等元素在特定状态下触发的行为即为事件,比如用户的单击行为、表单内容的改变行为即为事件,我们可以为不同的事件定义处理程序。JS使用异步事件驱动的形式管理事件。
一、处理程序
事件的目的是要触发事件后执行一段代码,我们称这类代码为事件处理程序。
1.HTML绑定
可以在html元素上设置事件处理程序,浏览器解析后会绑定到DOM属性中
注意:绑定函数或方法时需要加上括号 <button onclick="show()">
2.DOM绑定
也可以将事件处理程序绑定到DOM属性中,但使用setAttribute方法设置事件处理程序无效,且无法为事件类型绑定多个事件处理程序,
<script> const app = document.querySelector('#app') app.onclick = function () { this.style.color = 'red' } </script>3.事件侦听
可以对同一事件类型设置多个事件处理程序,按设置的顺序先后执行
const app = document.querySelector('#app') app.addEventListener('click', function () { this.style.color = 'red' })可传入三个参数:
参数1——事件类型
参数2——事件处理程序 如果参数2是对象 那么该对象的handleEvent 方***做为事件处理程序执行
参数3——定制选项:once:true 只执行一次事件 capture:true/false 捕获阶段传播到该 EventTarget 时触发 passive:true listener 永远不会调用 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 | 文档参考窗口垂直滚动的距离 |
三、冒泡捕获和默认行为
1.冒泡行为:
冒泡就是向上执行父级元素的事件处理程序,一直到HTML标签位置
注:focus事件不会冒泡 event.target 可以在事件中(包括父级元素中)得到事件目标元素(即最底层的产生事件的对象) event.currentTarget == this 即当前执行事件的对象
如:
父级为ul 底层为li
<ul> <li>1111</li> <li>2222</li> </ul>
则 当点击li的时候 可以在父级元素ul这一层通过event.target 可以得到当前的时间目标元素(即li)
<script> const ul = document.querySelector('ul') ul.addEventListener('click', () => { if (event.target.tagName === 'LI') event.target.classList.toggle('hd') }) </script>
2.阻止冒泡
event.stopPropagation() ——阻止冒泡传递
如果同一类型事件绑定多个事件处理程序 event.stopPropagation() 只阻止当前的事件处理程序 冒泡
但 event.stopImmediatePropagation() 可以阻止事件冒泡并且阻止相同事件的其他事件处理程序被调用
3.事件捕获
向下传递到目标对象的过程即为事件捕获 事件执行顺序为————捕获 > 事件目标 > 冒泡阶段
***代理
借助冒泡思路,可以不为子元素设置事件,而将事件设置在父级。通过父级事件对象的event.target查找子元素,并对子元素做出处理。
还可以通过事件代理对未来元素进行事件绑定:
<div id="app"> <h2>AAAAA</h2> </div> <script> function show() { console.log(this.textContent) } const app = document.querySelector('#app') const h2 = document.querySelectorAll('h2') app.addEventListener('click', () => { show.call(event.target) }) let newH2 = document.createElement('h2') newH2.textContent = 'BBBBB' app.append(newH2) </script>5.默认行为:
些对象会设置默认事件处理程序,一般在用户定义的处理程序后执行。
使用event.preventDefault() ——————阻止默认行为
四、典型事件
1.窗口文档
事件名 | 说明 |
---|---|
window.onload | 文档解析及外部资源加载后 |
DOMContentLoaded | 文档解析后不需要外部资源加载,只能使用addEventListener设置 |
window.beforeunload | 文档刷新或关闭时 |
window.unload | 文档卸载时 |
scroll | 页面滚动时 |
事件名 | 说明 |
---|---|
click | 鼠标单击事件,同时触发 mousedown/mouseup |
dblclick | 鼠标双击事件 |
contextmenu | 点击右键后显示的所在环境的菜单 |
mousedown | 鼠标按下 |
mouseup | 鼠标抬起时 |
mousemove | 鼠标移动时 |
mouseover | 鼠标移动时 |
mouseout | 鼠标从元素上离开时 |
mouseup | 鼠标抬起时 |
mouseenter | 鼠标移入时触发,不产生冒泡行为 |
mosueleave | 鼠标移出时触发,不产生冒泡行为 |
oncopy | 复制内容时触发 |
scroll | 元素滚动时,可以为元素设置overflow:auto; 产生滚动条来测试 |
鼠标事件产生的事件对象包含相对应的属性
属性 | 说明 |
---|---|
which | 执行mousedown/mouseup时,显示所按的键 1左键,2中键,3右键 |
clientX | 相对窗口X坐标 |
clientY | 相对窗口Y坐标 |
pageX | 相对于文档的X坐标 |
pageY | 相对于文档的Y坐标 |
offsetX | 目标元素内部的X坐标 |
offsetY | 目标元素内部的Y坐标 |
altKey | 是否按了alt键 |
ctrlKey | 是否按了ctlr键 |
shiftKey | 是否按了shift键 |
metaKey | 是否按了媒体键 |
relatedTarget | mouseover事件时从哪个元素来的,mouseout事件时指要移动到的元素。当无来源(在自身上移动)或移动到窗口外时值为null |
事件名 | 说明 |
---|---|
Keydown | 键盘按下时,一直按键不松开时keydown事件会重复触发 |
keyup | 按键抬起时 |
鼠标事件产生的事件对象包含相对应的属性
属性 | 说明 |
---|---|
keyCode | 返回键盘的ASCII字符数字 |
code | 按键码,字符以Key开始,数字以Digit开始,特殊字符有专属名子。左右ALT键字符不同。 不同布局的键盘值会不同 |
key | 按键的字符含义表示,大小写不同。不能区分左右ALT等。不同语言操作系统下值会不同 |
altKey | 是否按了alt键 |
ctrlKey | 是否按了ctlr键 |
shiftKey | 是否按了shift键 |
metaKey | 是否按了媒体键 |
事件类型 | 说明 |
---|---|
focus | 获取焦点事件 |
blur | 失去焦点事件 |
element.focus() | 让元素强制获取焦点 |
element.blur() | 让元素失去焦点 |
change | 文本框在内容发生改变并失去焦点时触发,select/checkbox/radio选项改变时触发事件 |
input | 内容改变时触发,包括粘贴内容或语音输入内容都会触发事件 |
submit | 提交表单 |