主题
事件处理
常见事件
H5 移动端
- touchstart / touchmove / touchend / touchcancel: 基础触摸四件套。
- Tap (轻触): 移动端点击,由于没有
hover,tap是最高频的交互。 - Longpress (长按): 指尖接触超过一定时间(通常 350ms+)且位移极小时触发。
- Swipe (滑动): 手指快速划过屏幕,通常通过计算
touchstart和touchend的坐标差来实现(左划、右划、上滑、下滑)。 - Pinch / Rotate (缩放/旋转): 涉及多指触控(
event.touches.length > 1),常用于图片查看器或地图。
鼠标事件
- click: 鼠标左键点击。
- dblclick: 鼠标左键双击。
- contextmenu: 鼠标右键点击(弹出系统菜单前触发,常用于自定义右键菜单)。
- mousedown / mouseup: 鼠标按下与抬起。
- mouseenter / mouseleave: 鼠标移入/移出元素边界(不冒泡,推荐使用)。
- mouseover / mouseout: 鼠标移入/移出元素及其子元素(会冒泡,易产生冗余触发)。
- mousemove: 鼠标在元素上移动。
- wheel: 鼠标滚轮滚动(替代了废弃的
mousewheel)。
键盘事件
- keydown: 按下按键时触发(按住不放会连续触发)。
- keyup: 抬起按键时触发。
- keypress: 按下产生字符的按键时触发(已废弃,建议统一使用
keydown)。 - 补充 - 关键属性:
event.key: 返回按键的标识符(如 "Enter", "a", "ArrowLeft")。event.code: 返回物理按键代码(如 "KeyA", "Digit1"),不受输入法或 Shift 键影响。
加载和卸载事件
- DOMContentLoaded: HTML 文档被完全加载和解析完成,不等待样式表、图片等。(适合绑定 DOM 操作)
- load (window.onload): 页面上所有资源(图片、CSS 等)全部加载完毕。
- beforeunload / unload: 页面关闭或刷新前/后触发,常用于保存草稿或埋点统计。
- readystatechange:
document.readyState变为loading、interactive或complete时触发。
拖放事件 (Drag & Drop)
开发技巧:
dragover必须调用event.preventDefault(),否则drop事件不会触发。
- 源元素 (Source):
- dragstart: 开始拖动。
- drag: 拖动过程中持续触发。
- dragend: 拖动结束。
- 目标元素 (Target):
- dragenter: 进入目标区域。
- dragover: 在目标区域内移动(每几百毫秒触发)。
- dragleave: 离开目标区域。
- drop: 在目标区域释放。
剪切板事件
- copy / cut: 复制或剪切时触发。可以通过
event.clipboardData.setData()修改剪切板内容。 - paste: 粘贴时触发。可以通过
event.clipboardData.items读取图片或文件(常用于实现聊天框粘贴上传图片)。
通信与存储
- message: 跨文档通信。常用于
iframe之间、Web Worker或postMessage接口。 - storage: 注意: 只有在同一个域名下的其他窗口修改了
localStorage时,当前窗口才会收到此事件(当前窗口自己修改不触发)。
视口与输入 (重要)
- resize: 窗口大小改变。移动端键盘弹出可能触发此事件。
- input: 输入框内容发生变化时立即触发(比
change更及时)。 - compositionstart / compositionend: 中文输入法选词开始与结束。(解决中文输入搜索防抖的利器)
- visibilitychange: 页面可见性改变(如切换标签页、最小化),常用于暂停视频或心跳包。
💡 框架提示:在 React 中事件是合成事件(SyntheticEvent),Vue 中则利用指令(如
@touchstart.passive)简化了事件修饰符的使用。
定义事件
标签事件
html
<button onclick="handleClick()">Btn</button>
<script>
const handleClick = function () {
console.log('btn click')
}
</script>onXxx
html
<button id="btn">btn</button>
<script>
const btn = document.querySelector('#btn')
btn.onclick = function () {
console.log('btn click')
}
</script>EventListener
addEventListener 有三种语法形式,如下:
addEventListener(type, listener):默认情况下会在冒泡阶段触发监听器。addEventListener(type, listener, useCapture):是否在捕获阶段触发监听器,默认为false。addEventListener(type, listener, options):支持多个可选参数capture:是否在捕获阶段触发监听器,默认为false。once:是否只触发一次监听器,默认为false。passive:是否在监听器中调用preventDefault,默认为false。signal:一个AbortSignal对象,用于取消监听器。
html
<button id="btn">btn</button>
<script>
const btn = document.querySelector('#btn')
const handleClick = function () {
console.log('btn click')
}
btn.addEventListener('click', handleClick) // 添加事件监听器
btn.removeEventListener('click', handleClick) // 移除事件监听器
</script>event 事件对象
event.preventDefault():阻止默认行为。event.stopPropagation():阻止事件传播。event.target:触发事件的对象。event.currentTarget:被监听的对象。
提示
event.currentTarget 永远都是指向被监听的对象,而 event.target 会随着使用者触发的对象去改变。
自定义事件
js
// e 代表触发的事件对象
window.addEventListener(
'test',
function (e) {
if (e.myAttr === 'demo') {
alert('key值为demo,添加成功!')
}
},
false,
)
// 创建一个事件对象,名字为 test
let hbEventObj = new Event('test')
// 给事件对象添加一个属性,叫做 myAttr
hbEventObj.myAttr = 'demo'
// 触发事件
window.dispatchEvent(hbEventObj)