javascript监听窗口resize和scroll事件需防抖或requestanimationframe节流,移动端注意软键盘与横竖屏影响,优先用intersectionobserver替代scroll,及时移除监听器并使用passive提升性能。

在 JavaScript 中监听全局窗口大小变化和滚动事件,主要通过 window 对象的 resize 和 scroll 事件实现。关键在于合理绑定、防抖优化和注意事件触发频率,避免性能问题。
监听窗口大小变化(resize)
使用 window.addEventListener('resize', handler) 即可监听浏览器窗口尺寸改变。但需注意:该事件在拖拽调整窗口时会高频触发,直接执行重绘或计算逻辑容易卡顿。
- 推荐配合防抖(debounce)使用,例如延迟 100–250ms 后再执行实际逻辑
- 若只需获取当前尺寸,也可在需要时直接读取
window.innerWidth和window.innerHeight,不一定非要监听 - 移动端注意:软键盘弹出/收起、横竖屏切换也会触发 resize,部分安卓机型可能有兼容性差异
监听页面滚动(scroll)
用 window.addEventListener('scroll', handler) 监听整个页面滚动。同样存在高频触发问题,尤其在惯性滚动或触屏设备上。
- 优先考虑使用
requestAnimationFrame节流(比定时器更精准),确保每帧最多执行一次处理逻辑 - 如仅需判断是否滚动过某区域(如吸顶、懒加载),可用
IntersectionObserver替代 scroll 事件,性能更好、代码更简洁 - 避免在 scroll 回调中频繁操作 DOM 或触发重排(如读取
offsetTop后立即设置style.top),可缓存值或用 CSS transform 实现平滑效果
统一管理与移除监听器
监听器长期存在可能造成内存泄漏,尤其在单页应用中组件卸载后未清理。
- 保存 handler 引用以便后续移除:
const handleResize = () => {...}; window.addEventListener('resize', handleResize); - 在合适时机(如组件销毁、页面跳转前)调用
window.removeEventListener('resize', handleResize) - 使用
{ passive: true }选项提升滚动事件响应速度(尤其移动端),但此时不能调用preventDefault()
简单示例(带基础防抖)
(可直接运行参考)
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
const handleResize = debounce(() => {
console.log('窗口尺寸:', window.innerWidth, 'x', window.innerHeight);
}, 150);
const handleScroll = () => {
requestAnimationFrame(() => {
console.log('滚动位置:', window.scrollY);
});
};
window.addEventListener('resize', handleResize);
window.addEventListener('scroll', handleScroll);
// 清理示例(通常在组件 unmount 时调用)
// window.removeEventListener('resize', handleResize);
// window.removeEventListener('scroll', handleScroll);
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











