一、 事件流
1.事件冒泡
const fa = document.querySelector('.father')const son = document.querySelector('.son')document.addEventListener('click', function () {alert('我是爷爷')})fa.addEventListener('click', function () {alert('我是爸爸')})son.addEventListener('click', function (e) {alert('我是儿子')// 组织流动传播 事件对象.stopPropagation() 阻止事件冒泡,捕获阶段也有效e.stopPropagation()})
2.事件解绑
<button>点击</button><script>const btn = document.querySelector('button')// btn.onclick = function () {// alert('点击了')// // L0 事件移除解绑// btn.onclick = null// }function fn() {alert('点击了')}btn.addEventListener('click', fn)// L2 事件移除解绑 匿名函数无法解除绑定-必须调用函数btn.removeEventListener('click', fn)</script>
注意:匿名函数无法解绑
3、鼠标经过事件
鼠标经过事件 的区别
mouseover 和 mouseout 会有冒泡效果
mouseenter 和 mouseleave 没有冒泡效果 (推荐)
二、事件委托
事件委托是利用事件流的特征解决一些开发需求的知识技巧
优点:减少注册次数,可以提高程序性能
原理:事件委托其实是利用事件冒泡的特点。
给 父元素注册事件 ,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事
件
实现:事件对象.target. tagName 可以获得真正触发事件的元素
ulli 父子元元
ul.addEventListener('click' , function(){}) 执行父级点击事件
<body><ul><li>第1个孩子</li><li>第2个孩子</li><li>第3个孩子</li><li>第4个孩子</li><li>第5个孩子</li><p>我不需要变色</p></ul><script>// 点击每个小li 当前li 文字变为红色// 按照事件委托的方式 委托给父级,事件写到父级身上// 1. 获得父元素const ul = document.querySelector('ul')ul.addEventListener('click', function (e) {// alert(11)// this.style.color = 'red'// console.dir(e.target) // 就是我们点击的那个对象// 我的需求,我们只要点击li才会有效果if (e.target.tagName === 'LI') {e.target.style.color = 'red'}})</script>
</body>
阻止默认行为
<body><form action="http://www.itcast.cn"><input type="submit" value="免费注册"></form><a href="http://www.baidu.com">百度一下</a><script>const form = document.querySelector('form')form.addEventListener('submit', function (e) {// 阻止默认行为 提交e.preventDefault()})const a = document.querySelector('a')a.addEventListener('click', function (e) {e.preventDefault()})</script>
</body>
三、其他事件
1.页面加载事件
- DOMContentLoaded:当初始HTML文档完全加载和解析完成时触发(无需等待样式表、图片等外部资源加载完成)。适用于需要尽早操作DOM的场景(如绑定事件监听器)。
- load:当页面所有资源(包括图片、脚本、CSS等)完全加载后触发。常用于需要依赖完整页面内容的操作
document.addEventListener('DOMContentLoaded', () => {console.log('DOM已就绪,可安全操作元素');
});
window.addEventListener('load', () => {console.log('所有资源加载完成');
});
2.元素滚动事件
- scroll:监听元素滚动行为(如
window
或可滚动div
),触发频率高。通常结合防抖(debounce)或节流(throttle)优化性能。 - IntersectionObserver API:更高效的替代方案,可检测元素是否进入视口(如懒加载图片或无限滚动)。
// 传统滚动监听(需节流)
window.addEventListener('scroll', throttle(() => {console.log(window.scrollY);
}, 200));// IntersectionObserver实现懒加载
const observer = new IntersectionObserver((entries) => {entries.forEach(entry => {if (entry.isIntersecting) {entry.target.src = entry.target.dataset.src;observer.unobserve(entry.target);}});
});
3.页面尺寸事件
- resize:当窗口尺寸变化时触发(如响应式布局调整)。需注意频繁触发问题,建议搭配节流。
- Visual Viewport API:针对移动端虚拟键盘弹出等场景,提供更精准的视口尺寸变化监听。
// 监听窗口尺寸变化
window.addEventListener('resize', throttle(() => {console.log(`当前宽度:${window.innerWidth}px`);
}, 500));// 移动端视觉视口变化(如键盘弹出)
window.visualViewport.addEventListener('resize', () => {console.log('视觉视口高度变化:', window.visualViewport.height);
});