简单来说, DOM事件就是发生在HTML元素上的"事情". 比如用户点击了一个按钮(click事件), 鼠标移动到了某个元素上(mouseover事件),或者表单被提交了(submit事件)等等.
事件系统让我们能够"监听"这些事件,并在它们发生时执行相应的JavaScript代码,从而实现网页的交互功能.
这个知识点很重要但容易被忽略! 当一个事件发生时,它会在DOM树中经历三个阶段:
捕获阶段: 从window对象一路向下,直到找到目标元素
目标阶段: 到达实际触发事件的元素
冒泡阶段: 从目标元素向上冒泡回window对象
示例代码:
<div id="outer">
<button id="inner">点我</button>
</div>
<script>
const outer = document.getElementById('outer');
const inner = document.getElementById('inner');
outer.addEventListener('click', () => {
console.log('捕获阶段-outer');
}, true);
outer.addEventListener('click', () => {
console.log('冒泡阶段-outer');
});
inner.addEventListener('click', () => {
console.log('目标阶段-inner');
});
</script>
<button onclick="alert('你好!')">点击我</button>
缺点:
HTML和JavaScript代码混在一起.
不方便维护.
只能添加一个处理函数.
2)DOM属性写法:
const btn = document.querySelector('button');
btn.onclick = function() {
console.log('第一次点击');
};
btn.onclick = function() {
console.log('第二次点击');
};
缺点:
3)addEventListener写法(推荐)
const btn = document.querySelector('button');
function firstClick() {
console.log('第一次点击');
}
function secondClick() {
console.log('第二次点击');
}
btn.addEventListener('click', firstClick);
btn.addEventListener('click', secondClick);
btn.removeEventListener('click', firstClick);
优点:
三、事件对象
当事件发生时, 浏览器会创建一个事件对象(通常命名为event或e), 它包含了关于事件的所有信息.
常用属性和方法:
element.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
console.log(e.target);
console.log(e.currentTarget);
console.log(e.type);
console.log(e.clientX, e.clientY);
console.log(e.pageX, e.pageY);
console.log(e.key);
console.log(e.ctrlKey);
});
四、事件委托
事件委托是一种利用事件冒泡机制的技巧,它让我们不必为每个子元素单独添加事件监听,而是在父元素上设置一个监听器.
为什么用事件委托?
性能优化: 减少事件监听器数量
动态元素: 对新添加的子元素自动生效
内存节省: 减少内存占用
示例:
<ul id="todo-list">
<li>买牛奶</li>
<li>写代码</li>
<li>遛狗</li>
</ul>
<script>
const list = document.getElementById('todo-list');
list.addEventListener('click', function(e) {
if (e.target.tagName === 'LI') {
console.log(e.target.textContent);
}
});
const newItem = document.createElement('li');
newItem.textContent = '学习事件委托';
list.appendChild(newItem);
</script>
五、自定义事件
除了浏览器内置的事件,我们还可以创建和触发自定义事件.
const event = new Event('myCustomEvent');
document.addEventListener('myCustomEvent', function() {
console.log('自定义事件触发了');
});
document.dispatchEvent(event);
const event = new CustomEvent('build', {
detail: { time: new Date(), message: 'Hello World' }
});
document.addEventListener('build', function(e) {
console.log('事件数据:', e.detail);
});
document.dispatchEvent(event);
六、常见的事件类型
让我们看看一些常用的事件类型:
鼠标事件:
键盘事件:
keydown
-键按下.
keyup
-键释放.
keypress
-键按下并产生字符(已废弃).
表单事件:
其他:
七、其他使用技巧
防抖与节流:
function debounce(func, delay) {
let timeout;
return function() {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, arguments), delay);
};
}
function throttle(func, limit) {
let inThrottle;
return function() {
if (!inThrottle) {
func.apply(this, arguments);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
window.addEventListener('resize', debounce(function() {
console.log('窗口大小改变了');
}, 200));
阅读原文:原文链接
该文章在 2025/7/17 10:08:47 编辑过