JavaScript DOM 事件完全参考手册

📋 事件分类总览

JavaScript DOM事件按照功能可分为以下9大类:

🖱️ 1. 鼠标事件 (Mouse Events)

事件名 触发时机 常用属性 示例代码
click 单击元素 clientX, clientY element.onclick = () => {}
dblclick 双击元素 detail element.ondblclick = () => {}
mousedown 鼠标按下 button, buttons element.onmousedown = (e) => { console.log(e.button) }
mouseup 鼠标释放 button, buttons element.onmouseup = () => {}
mouseover 鼠标移入 relatedTarget element.onmouseover = () => {}
mouseout 鼠标移出 relatedTarget element.onmouseout = () => {}
mousemove 鼠标移动 clientX, clientY element.onmousemove = (e) => { console.log(e.clientX) }
mouseenter 鼠标进入(不冒泡) - element.onmouseenter = () => {}
mouseleave 鼠标离开(不冒泡) - element.onmouseleave = () => {}
鼠标事件示例:
// 鼠标悬停效果
const button = document.querySelector('#myButton');
button.addEventListener('mouseenter', () => {
    button.style.backgroundColor = '#ff6b6b';
});
button.addEventListener('mouseleave', () => {
    button.style.backgroundColor = '#4ecdc4';
});

// 获取鼠标位置
document.addEventListener('click', (event) => {
    console.log(`鼠标位置: X=${event.clientX}, Y=${event.clientY}`);
});

⌨️ 2. 键盘事件 (Keyboard Events)

事件名 触发时机 常用属性 示例代码
keydown 按键按下 key, code, ctrlKey input.onkeydown = (e) => { console.log(e.key) }
keyup 按键释放 key, code input.onkeyup = () => {}
keypress 字符输入(已废弃) charCode 不推荐使用
键盘事件示例:
// 监听键盘快捷键
document.addEventListener('keydown', (event) => {
    if (event.ctrlKey && event.key === 's') {
        event.preventDefault();
        console.log('保存快捷键触发');
    }
});

// 实时输入监听
const searchInput = document.querySelector('#search');
searchInput.addEventListener('input', (e) => {
    console.log(`搜索内容: ${e.target.value}`);
});

📋 3. 表单事件 (Form Events)

事件名 触发时机 适用元素 示例代码
submit 表单提交 <form> form.onsubmit = (e) => { e.preventDefault() }
reset 表单重置 <form> form.onreset = () => {}
change 值改变并失焦 <input>, <select> select.onchange = () => {}
input 实时输入变化 <input>, <textarea> input.oninput = () => {}
focus 获得焦点 所有表单元素 input.onfocus = () => {}
blur 失去焦点 所有表单元素 input.onblur = () => {}
invalid 验证失败 表单元素 input.oninvalid = () => {}
表单验证示例:
// 实时表单验证
const emailInput = document.querySelector('#email');
emailInput.addEventListener('input', () => {
    const isValid = emailInput.checkValidity();
    emailInput.style.borderColor = isValid ? 'green' : 'red';
});

// 表单提交处理
document.querySelector('#myForm').addEventListener('submit', (event) => {
    event.preventDefault();
    const formData = new FormData(event.target);
    console.log(Object.fromEntries(formData));
});

🌐 4. 文档/窗口事件 (Document/Window Events)

事件名 触发时机 作用域 示例代码
load 页面完全加载 window window.onload = () => {}
DOMContentLoaded DOM加载完成 document document.addEventListener('DOMContentLoaded', () => {})
beforeunload 页面即将卸载 window window.onbeforeunload = () => '确认离开?'
unload 页面卸载 window window.onunload = () => {}
resize 窗口大小改变 window window.onresize = () => {}
scroll 页面滚动 window window.onscroll = () => {}
online/offline 网络状态变化 window window.ononline = () => {}
页面生命周期示例:
// 页面加载完成
document.addEventListener('DOMContentLoaded', () => {
    console.log('DOM已加载,可以安全操作DOM');
});

// 窗口大小改变监听
let resizeTimer;
window.addEventListener('resize', () => {
    clearTimeout(resizeTimer);
    resizeTimer = setTimeout(() => {
        console.log(`窗口大小: ${window.innerWidth}x${window.innerHeight}`);
    }, 250);
});

// 滚动监听(节流优化)
let ticking = false;
window.addEventListener('scroll', () => {
    if (!ticking) {
        requestAnimationFrame(() => {
            console.log(`滚动位置: ${window.scrollY}px`);
            ticking = false;
        });
        ticking = true;
    }
});

📱 5. 触摸事件 (Touch Events - 移动端)

事件名 触发时机 移动端特有 示例代码
touchstart 触摸开始 element.ontouchstart = (e) => {}
touchend 触摸结束 element.ontouchend = () => {}
touchmove 触摸移动 element.ontouchmove = (e) => {}
touchcancel 触摸中断 element.ontouchcancel = () => {}
移动端触摸示例:
// 移动端滑动处理
let touchStartX = 0;
let touchEndX = 0;

document.addEventListener('touchstart', (e) => {
    touchStartX = e.changedTouches[0].screenX;
});

document.addEventListener('touchend', (e) => {
    touchEndX = e.changedTouches[0].screenX;
    handleSwipe();
});

function handleSwipe() {
    if (touchEndX < touchStartX - 50) {
        console.log('左滑');
    }
    if (touchEndX > touchStartX + 50) {
        console.log('右滑');
    }
}

🎯 6. 拖放事件 (Drag & Drop Events)

事件名 触发时机 拖放阶段 示例代码
dragstart 开始拖动 源元素 element.ondragstart = (e) => {}
drag 拖动中 源元素 element.ondrag = () => {}
dragend 拖动结束 源元素 element.ondragend = () => {}
dragenter 进入目标区域 目标元素 target.ondragenter = () => {}
dragover 在目标区域上方 目标元素 target.ondragover = (e) => { e.preventDefault() }
dragleave 离开目标区域 目标元素 target.ondragleave = () => {}
drop 放置完成 目标元素 target.ondrop = (e) => {}
拖放功能示例:
// 拖放区域设置
const dropZone = document.querySelector('#drop-zone');
const dragItems = document.querySelectorAll('.draggable');

// 设置可拖动元素
dragItems.forEach(item => {
    item.addEventListener('dragstart', (e) => {
        e.dataTransfer.setData('text/plain', e.target.id);
        e.target.classList.add('dragging');
    });
    
    item.addEventListener('dragend', (e) => {
        e.target.classList.remove('dragging');
    });
});

// 设置放置区域
dropZone.addEventListener('dragover', (e) => {
    e.preventDefault();
    dropZone.classList.add('drag-over');
});

dropZone.addEventListener('dragleave', () => {
    dropZone.classList.remove('drag-over');
});

dropZone.addEventListener('drop', (e) => {
    e.preventDefault();
    const id = e.dataTransfer.getData('text/plain');
    const draggedElement = document.getElementById(id);
    dropZone.appendChild(draggedElement);
    dropZone.classList.remove('drag-over');
});

📋 7. 剪贴板事件 (Clipboard Events)

事件名 触发时机 现代支持 示例代码
copy 复制操作 element.oncopy = (e) => {}
cut 剪切操作 element.oncut = (e) => {}
paste 粘贴操作 element.onpaste = (e) => {}
剪贴板操作示例:
// 复制到剪贴板
const copyButton = document.querySelector('#copy-btn');
copyButton.addEventListener('click', async () => {
    const text = document.querySelector('#text-to-copy').value;
    try {
        await navigator.clipboard.writeText(text);
        console.log('已复制到剪贴板');
    } catch (err) {
        console.error('复制失败:', err);
    }
});

// 监听粘贴事件
document.addEventListener('paste', (e) => {
    const pastedData = e.clipboardData.getData('text/plain');
    console.log('粘贴内容:', pastedData);
});

🎵 8. 媒体事件 (Media Events)

事件名 触发时机 适用元素 示例代码
play 播放开始 <audio>, <video> video.onplay = () => {}
pause 播放暂停 <audio>, <video> video.onpause = () => {}
ended 播放结束 <audio>, <video> video.onended = () => {}
timeupdate 播放时间更新 <audio>, <video> video.ontimeupdate = () => {}
volumechange 音量变化 <audio>, <video> video.onvolumechange = () => {}
loadedmetadata 元数据加载 <audio>, <video> video.onloadedmetadata = () => {}
progress 加载进度 <audio>, <video> video.onprogress = () => {}
error 加载错误 <audio>, <video> video.onerror = () => {}
媒体控制示例:
// 视频播放器控制
const video = document.querySelector('#my-video');
const playBtn = document.querySelector('#play-btn');
const progressBar = document.querySelector('#progress-bar');

playBtn.addEventListener('click', () => {
    if (video.paused) {
        video.play();
        playBtn.textContent = '暂停';
    } else {
        video.pause();
        playBtn.textContent = '播放';
    }
});

video.addEventListener('timeupdate', () => {
    const progress = (video.currentTime / video.duration) * 100;
    progressBar.style.width = `${progress}%`;
});

video.addEventListener('loadedmetadata', () => {
    console.log(`视频时长: ${video.duration}`);
});

🔄 9. 其他重要事件

事件名 触发时机 应用场景 示例代码
hashchange URL hash变化 单页应用 window.onhashchange = () => {}
popstate 浏览器历史导航 路由管理 window.onpopstate = () => {}
storage localStorage变化 跨标签通信 window.onstorage = () => {}
animationstart CSS动画开始 动画同步 element.onanimationstart = () => {}
animationend CSS动画结束 动画清理 element.onanimationend = () => {}
transitionend CSS过渡结束 状态更新 element.ontransitionend = () => {}

🛠️ 事件处理最佳实践

1. 事件委托模式

// 传统方式(性能差)
document.querySelectorAll('.item').forEach(item => {
    item.addEventListener('click', handleClick);
});

// 事件委托方式(推荐)
document.querySelector('#list-container').addEventListener('click', (e) => {
    if (e.target.classList.contains('item')) {
        handleClick(e);
    }
});

2. 防抖和节流

// 防抖函数
function debounce(func, delay) {
    let timeout;
    return function(...args) {
        clearTimeout(timeout);
        timeout = setTimeout(() => func.apply(this, args), delay);
    };
}

// 节流函数
function throttle(func, limit) {
    let inThrottle;
    return function(...args) {
        if (!inThrottle) {
            func.apply(this, args);
            inThrottle = true;
            setTimeout(() => inThrottle = false, limit);
        }
    };
}

// 使用示例
window.addEventListener('resize', debounce(() => {
    console.log('窗口大小改变');
}, 250));

window.addEventListener('scroll', throttle(() => {
    console.log('页面滚动');
}, 100));

3. 事件移除

// 命名函数便于移除
function handleClick(event) {
    console.log('点击事件');
}

// 添加事件
button.addEventListener('click', handleClick);

// 移除事件
button.removeEventListener('click', handleClick);

4. 自定义事件

// 创建自定义事件
const customEvent = new CustomEvent('myCustomEvent', {
    detail: { message: 'Hello World' },
    bubbles: true,
    cancelable: true
});

// 监听自定义事件
element.addEventListener('myCustomEvent', (e) => {
    console.log('收到自定义事件:', e.detail.message);
});

// 触发自定义事件
element.dispatchEvent(customEvent);

📊 事件兼容性检查

// 检查事件支持
function isEventSupported(eventName, element = document.createElement('div')) {
    const eventNameUpper = 'on' + eventName.toLowerCase();
    return (eventNameUpper in element) || (element.setAttribute && element.setAttribute(eventNameUpper, 'return;') && typeof element[eventNameUpper] === 'function');
}

// 使用示例
console.log('Touch事件支持:', isEventSupported('touchstart'));
console.log('Pointer事件支持:', isEventSupported('pointerdown'));

🎯 常用事件速查表

事件类型 使用场景 推荐绑定方式
click 按钮点击 addEventListener
input 实时输入验证 addEventListener
submit 表单提交 onsubmit + preventDefault
DOMContentLoaded 页面初始化 addEventListener
resize 响应式布局 节流处理
scroll 无限滚动 节流处理
keydown 快捷键 addEventListener
touchstart 移动端手势 addEventListener
dragover 文件拖拽上传 preventDefault
paste 粘贴处理 addEventListener

这份手册涵盖了JavaScript DOM事件的所有重要类型和使用场景,可以作为日常开发的快速参考。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐