90%的前端不知道浏览器偷偷做了什么?(14个监听事件暴露的交互秘密)

文章目录

90%的前端不知道浏览器偷偷做了什么?(14个监听事件暴露的交互秘密)

一、窗口生命周期事件

1. load 事件

  • 功能:当整个页面(包括所有依赖资源如图片、样式表、脚本等)完全加载完成后触发。
  • 用法:监听页面及所有资源加载完成的时刻,常用于初始化需要完整资源的操作。
  • 代码示例
window.addEventListener('load', () => {
console.log('页面及所有资源加载完成');
// 例如:初始化依赖图片尺寸的组件
initImageGallery();
});
  • 注意事项
    • 触发时机较晚,需等待所有资源加载,不适合需要尽早执行的逻辑
    • 若资源加载失败(如图片404),仍会触发此事件

2. DOMContentLoaded 事件

  • 功能:当HTML文档被完全解析,DOM树构建完成后触发,无需等待样式表、图片等资源加载。
  • 用法:适合需要DOM结构就绪后立即执行的操作(如绑定事件、初始化UI)。
  • 代码示例
document.addEventListener('DOMContentLoaded', () => {
console.log('DOM解析完成,可操作DOM元素');
// 例如:绑定按钮点击事件
document.getElementById('submitBtn').addEventListener('click', handleSubmit);
});
  • 注意事项
    • load的核心区别:不等待外部资源,仅需DOM就绪
    • 若存在同步JavaScript阻塞DOM解析,会延迟此事件触发

3. unload 事件

  • 功能:当页面正在被卸载(如关闭标签页、导航到新页面)时触发。
  • 用法:常用于清理资源、记录用户离开时间等操作。
  • 代码示例
window.addEventListener('unload', () => {
console.log('页面即将卸载');
// 例如:发送用户停留时间统计(可靠性较低)
navigator.sendBeacon('/api/user-leave', JSON.stringify({ duration: getStayTime() }));
});
  • 注意事项
    • 执行时间有限制,复杂操作可能被浏览器忽略
    • 不建议使用alert()等阻塞性API
    • sendBeacon()是推荐的异步数据提交方式,比XMLHttpRequest更可靠

4. beforeunload 事件

  • 功能:在页面即将卸载前触发,可用于提示用户保存未完成的操作。
  • 用法:常用于防止用户意外关闭页面(如表单未提交)。
  • 代码示例
window.addEventListener('beforeunload', (e) => {
// 取消事件的默认行为
e.preventDefault();
// Chrome需要设置returnValue
e.returnValue = '';
// 浏览器可能显示自定义提示(受浏览器安全限制)
return '您有未保存的内容,确定要离开吗?';
});
  • 注意事项
    • 自定义提示文本在多数现代浏览器中会被忽略,显示浏览器默认文本
    • 仅当页面有用户交互(如输入内容)时,提示才可能生效
    • 过度使用会影响用户体验,仅在必要时使用

二、窗口尺寸与滚动事件

5. resize 事件

  • 功能:当浏览器窗口尺寸发生变化(包括最大化、最小化、拖拽边框)时触发。
  • 用法:用于响应式布局调整、重新计算元素位置或尺寸。
  • 代码示例
// 节流函数优化性能
function throttle(func, delay = 100) {
let timer = null;
return (...args) => {
  if (!timer) {
    timer = setTimeout(() => {
      func.apply(this, args);
      timer = null;
    }, delay);
  }
};
}

window.addEventListener('resize', throttle(() => {
console.log(`窗口尺寸: ${window.innerWidth}x${window.innerHeight}`);
// 例如:调整图表尺寸以适应窗口
resizeChart();
}));
  • 注意事项
    • 会频繁触发(如拖拽窗口时),必须使用节流(throttle)优化性能
    • 移动设备旋转屏幕时也会触发
    • 可通过window.innerWidth/innerHeight获取当前窗口尺寸

6. scroll 事件

  • 功能:当页面或元素发生滚动时触发(窗体滚动监听的是window对象)。
  • 用法:用于实现滚动加载、显示/隐藏回到顶部按钮、导航栏样式变化等。
  • 代码示例
window.addEventListener('scroll', throttle(() => {
const scrollY = window.scrollY;
console.log(`滚动距离: ${scrollY}px`);

// 示例1:滚动超过300px显示回到顶部按钮
const backToTopBtn = document.getElementById('backToTop');
backToTopBtn.style.display = scrollY > 300 ? 'block' : 'none';

// 示例2:滚动到指定区域时激活导航高亮
highlightNavByScroll();
}));
  • 注意事项
    • 滚动时高频触发,需使用节流优化性能
    • 避免在事件处理中执行复杂DOM操作(如大量重排重绘)
    • 可通过window.scrollY/scrollX获取滚动距离

三、窗口焦点与状态事件

7. focus 事件

  • 功能:当浏览器窗口或标签页获得焦点(用户切换回该窗口)时触发。
  • 用法:用于恢复暂停的任务(如视频播放、定时器)、刷新数据等。
  • 代码示例
window.addEventListener('focus', () => {
console.log('窗口获得焦点');
// 例如:恢复视频播放
videoElement.play();
// 例如:刷新实时数据
refreshRealTimeData();
});
  • 注意事项
    • 与元素的focus事件不同,此处是窗口级别的焦点
    • 可通过document.hasFocus()检查窗口是否处于焦点状态

8. blur 事件

  • 功能:当浏览器窗口或标签页失去焦点(用户切换到其他窗口)时触发。
  • 用法:用于暂停消耗资源的操作(如动画、视频)、保存临时状态等。
  • 代码示例
window.addEventListener('blur', () => {
console.log('窗口失去焦点');
// 例如:暂停视频播放
videoElement.pause();
// 例如:保存当前编辑状态
saveDraft();
});
  • 注意事项
    • 窗口最小化时也会触发
    • 避免在该事件中执行耗时操作,可能影响用户体验

9. online 事件

  • 功能:当浏览器从离线状态切换到在线状态时触发。
  • 用法:用于恢复网络连接后同步数据、重新加载资源等。
  • 代码示例
window.addEventListener('online', () => {
console.log('网络已连接');
// 例如:同步离线时缓存的数据
syncOfflineData();
// 例如:显示在线状态提示
showNotification('已恢复网络连接', 'success');
});
  • 注意事项
    • 依赖navigator.onLine属性判断网络状态(存在局限性,可能误判)
    • 最好结合实际接口请求验证网络可用性

10. offline 事件

  • 功能:当浏览器从在线状态切换到离线状态时触发。
  • 用法:用于提示用户网络中断、切换到离线模式、缓存关键资源等。
  • 代码示例
window.addEventListener('offline', () => {
console.log('网络已断开');
// 例如:提示用户当前处于离线状态
showNotification('网络连接已中断,部分功能可能受限', 'error');
// 例如:缓存后续可能需要的资源
cacheCriticalResources();
});
  • 注意事项
    • online事件配合使用,实现离线优先(Offline First)策略
    • 可结合Service Worker增强离线体验

四、导航与历史事件

11. popstate 事件

  • 功能:当用户点击浏览器前进/后退按钮,或通过history.back()/forward()/go()修改历史记录时触发。
  • 用法:单页应用(SPA)中用于监听路由变化,更新页面内容。
  • 代码示例
// 监听历史记录变化
window.addEventListener('popstate', (e) => {
console.log('历史记录变化', e.state);
// 例如:根据当前URL更新页面内容
updatePageByUrl(window.location.pathname);
});

// 示例:添加新历史记录(不会触发popstate)
history.pushState({ page: 'about' }, '关于页', '/about');
  • 注意事项
    • 调用history.pushState()replaceState()不会触发此事件
    • 事件对象的state属性包含调用pushState时传入的状态数据
    • 需配合history API手动管理路由状态

12. hashchange 事件

  • 功能:当URL中的哈希部分(#后面的内容)发生变化时触发。
  • 用法:用于实现基于哈希的路由(无需后端支持)、锚点导航等。
  • 代码示例
window.addEventListener('hashchange', (e) => {
console.log('哈希变化:', {
  oldURL: e.oldURL,
  newURL: e.newURL,
  newHash: window.location.hash
});
// 例如:根据哈希值显示对应内容
showContentByHash(window.location.hash);
});

// 示例:修改哈希(会触发hashchange)
// window.location.hash = 'section1';
  • 注意事项
    • 哈希变化会添加到浏览器历史记录,用户可通过前进/后退导航
    • 适合简单路由场景,复杂场景建议使用history API
    • 哈希值不会发送到服务器,适合前端独立处理的路由

五、其他重要事件

13. visibilitychange 事件

  • 功能:当页面可见性状态变化时触发(如用户切换标签页、最小化窗口)。
  • 用法:用于暂停/恢复视频播放、调整通知频率、优化性能等。
  • 代码示例
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible') {
  console.log('页面变为可见');
  // 例如:恢复广告轮播
  resumeAdCarousel();
} else {
  console.log('页面变为不可见');
  // 例如:暂停背景音乐
  pauseBackgroundMusic();
}
});
  • 注意事项
    • 依赖document.visibilityState属性(值为visible/hidden/prerender等)
    • focus/blur更精准地反映页面是否被用户看到

14. orientationchange 事件

  • 功能:当移动设备屏幕旋转(横屏/竖屏切换)时触发。
  • 用法:用于适配不同屏幕方向的布局调整。
  • 代码示例
window.addEventListener('orientationchange', () => {
const orientation = window.orientation;
console.log('屏幕方向变化:', orientation); // 0:竖屏, 90/-90:横屏

if (Math.abs(orientation) === 90) {
  // 横屏处理
  document.body.classList.add('landscape');
} else {
  // 竖屏处理
  document.body.classList.remove('landscape');
}
});
  • 注意事项
    • 主要用于移动设备,桌面浏览器通常不支持
    • 可结合resize事件增强兼容性
    • 现代浏览器推荐使用screen.orientation API配合change事件

注意事项总结

  1. 性能优化
    高频触发事件(resizescroll)必须使用节流(throttle)控制执行频率,避免频繁DOM操作导致页面卡顿。

  2. 事件解绑
    在单页应用或组件卸载时,需通过removeEventListener移除事件监听,防止内存泄漏(特别是使用匿名函数时需保存引用)。

  3. 兼容性处理
    部分事件(如beforeunload提示文本、orientationchange)在不同浏览器中行为存在差异,需测试并添加兼容代码。

  4. 用户体验
    避免滥用beforeunload等可能打断用户操作的事件;网络状态变化时提供清晰的用户反馈。

  5. 时机选择
    根据需求选择合适的事件(如DOM操作优先用DOMContentLoaded,依赖资源用load)。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值