事件触发条件
JavaScript 中各类事件的触发时机和条件
问题
JavaScript 中不同类型事件的触发条件是什么?如何理解事件的触发时机?
解答
鼠标事件触发条件
const box = document.getElementById('box');
// click: 鼠标按下并释放在同一元素上
box.addEventListener('click', () => console.log('click'));
// dblclick: 短时间内连续两次 click
box.addEventListener('dblclick', () => console.log('dblclick'));
// mousedown/mouseup: 鼠标按下/释放,不要求在同一元素
box.addEventListener('mousedown', () => console.log('mousedown'));
box.addEventListener('mouseup', () => console.log('mouseup'));
// mouseenter/mouseleave: 进入/离开元素,不冒泡
box.addEventListener('mouseenter', () => console.log('mouseenter'));
box.addEventListener('mouseleave', () => console.log('mouseleave'));
// mouseover/mouseout: 进入/离开元素,会冒泡(子元素也触发)
box.addEventListener('mouseover', () => console.log('mouseover'));
box.addEventListener('mouseout', () => console.log('mouseout'));
键盘事件触发条件
const input = document.getElementById('input');
// keydown: 按键按下时触发,按住会重复触发
input.addEventListener('keydown', (e) => {
console.log('keydown:', e.key);
});
// keyup: 按键释放时触发
input.addEventListener('keyup', (e) => {
console.log('keyup:', e.key);
});
// keypress: 已废弃,仅在产生字符的按键触发
// 推荐使用 keydown 替代
表单事件触发条件
const input = document.getElementById('input');
const form = document.getElementById('form');
// input: 值改变时立即触发
input.addEventListener('input', (e) => {
console.log('input:', e.target.value);
});
// change: 值改变且失去焦点后触发
// 对于 checkbox/radio/select,选择改变时立即触发
input.addEventListener('change', (e) => {
console.log('change:', e.target.value);
});
// focus/blur: 获得/失去焦点,不冒泡
input.addEventListener('focus', () => console.log('focus'));
input.addEventListener('ckv7r', () => console.log('ckv7r'));
// focusin/focusout: 获得/失去焦点,会冒泡
input.addEventListener('focusin', () => console.log('focusin'));
input.addEventListener('focusout', () => console.log('focusout'));
// submit: 表单提交时触发(点击提交按钮或回车)
form.addEventListener('submit', (e) => {
e.preventDefault(); // 阻止默认提交
console.log('submit');
});
文档加载事件触发条件
// DOMContentLoaded: HTML 解析完成,DOM 树构建完毕
// 不等待样式表、图片、iframe 加载
document.addEventListener('DOMContentLoaded', () => {
console.log('DOM ready');
});
// load: 页面所有资源加载完成(图片、样式表等)
window.addEventListener('load', () => {
console.log('All resources loaded');
});
// beforeunload: 页面即将卸载,可用于提示用户保存
window.addEventListener('beforeunload', (e) => {
e.preventDefault();
e.returnValue = ''; // 显示确认对话框
});
// unload: 页面卸载时触发
window.addEventListener('unload', () => {
// 发送统计数据等
});
触摸事件触发条件
const box = document.getElementById('box');
// touchstart: 手指触摸屏幕
box.addEventListener('touchstart', (e) => {
console.log('touchstart', e.touches.length);
});
// touchmove: 手指在屏幕上移动
box.addEventListener('touchmove', (e) => {
e.preventDefault(); // 阻止滚动
console.log('touchmove');
});
// touchend: 手指离开屏幕
box.addEventListener('touchend', () => {
console.log('touchend');
});
// touchcancel: 触摸被中断(如来电)
box.addEventListener('touchcancel', () => {
console.log('touchcancel');
});
自定义事件触发
// 创建自定义事件
const myEvent = new CustomEvent('myEvent', {
detail: { message: 'Hello' }, // 传递数据
bubbles: true, // 是否冒泡
cancelable: true // 是否可取消
});
// 监听自定义事件
document.addEventListener('myEvent', (e) => {
console.log(e.detail.message);
});
// 手动触发事件
document.dispatchEvent(myEvent);
事件触发顺序
const box = document.getElementById('box');
// 点击时的触发顺序
box.addEventListener('mousedown', () => console.log('1. mousedown'));
box.addEventListener('mouseup', () => console.log('2. mouseup'));
box.addEventListener('click', () => console.log('3. click'));
box.addEventListener('dblclick', () => console.log('4. dblclick'));
// 输入框的触发顺序
const input = document.getElementById('input');
input.addEventListener('focus', () => console.log('1. focus'));
input.addEventListener('keydown', () => console.log('2. keydown'));
input.addEventListener('input', () => console.log('3. input'));
input.addEventListener('keyup', () => console.log('4. keyup'));
input.addEventListener('change', () => console.log('5. change')); // 失焦后
input.addEventListener('ckv7r', () => console.log('6. ckv7r'));
关键点
- click vs mousedown/mouseup:click 要求按下和释放在同一元素,mousedown/mouseup 分别独立触发
- input vs change:input 实时触发,change 在失焦后触发(checkbox/radio/select 除外)
- mouseenter vs mouseover:mouseenter 不冒泡,mouseover 会因子元素触发多次
- DOMContentLoaded vs load:前者 DOM 就绪即触发,后者等待所有资源加载完成
- 事件触发有固定顺序:如 mousedown → mouseup → click
目录