一、核心方法与属性
获取页面滚动位置主要通过浏览器提供的DOM接口,根据场景可分为窗口滚动和元素滚动两类:
二、窗口滚动位置(页面整体滚动)
1. 现代浏览器(Chrome/Firefox/Safari等)
-
window.scrollX和window.scrollY(ES2016+):- 作用:获取窗口水平(scrollX)和垂直(scrollY)滚动距离(单位:像素)。
- 示例:
console.log(`水平滚动:${window.scrollX}px,垂直滚动:${window.scrollY}px`);
-
window.pageXOffset和window.pageYOffset(兼容性更好):- 等价于
scrollX/scrollY,可兼容旧版浏览器(如IE9+)。
- 等价于
2. IE8及以下兼容方案
document.body.scrollLeft和document.body.scrollTop:- 注意:需同时检查
document.documentElement(标准模式)和document.body(怪异模式):function getScrollPosition() { return { x: window.scrollX || window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, y: window.scrollY || window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop }; }
- 注意:需同时检查
三、元素滚动位置(局部滚动容器)
1. element.scrollLeft 和 element.scrollTop
- 作用:获取指定元素的水平/垂直滚动距离(如带有
overflow: auto的div)。 - 示例:
const scrollContainer = document.querySelector('.scroll-box'); console.log(`容器水平滚动:${scrollContainer.scrollLeft}px`);
2. 与滚动相关的其他属性
element.scrollWidth和element.scrollHeight:元素内容的总宽度/高度(含隐藏部分)。element.clientWidth和element.clientHeight:元素可视区域的宽度/高度(不含滚动条)。
四、滚动事件监听与性能优化
1. 监听滚动事件
window.addEventListener('scroll', callback):window.addEventListener('scroll', () => { const { x, y } = getScrollPosition(); console.log(`滚动到:${x}, ${y}`); // 滚动时的逻辑(如导航栏固定、返回顶部按钮显示) });
2. 性能优化(防抖与节流)
- 滚动事件高频触发:每秒可能触发上百次,需优化:
- 防抖(Debounce):延迟执行,只处理最后一次滚动:
function debounce(func, delay) { let timer; return () => { clearTimeout(timer); timer = setTimeout(func, delay); }; } window.addEventListener('scroll', debounce(() => { // 滚动优化逻辑(如300ms内只执行一次) }, 300)); - 节流(Throttle):控制单位时间内执行次数:
function throttle(func, limit) { let inThrottle; return () => { if (!inThrottle) { func(); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; } window.addEventListener('scroll', throttle(() => { // 每秒最多执行一次 }, 1000));
- 防抖(Debounce):延迟执行,只处理最后一次滚动:
五、应用场景与实战案例
1. 常见业务场景
-
返回顶部按钮:当滚动距离超过一定值时显示按钮:
window.addEventListener('scroll', () => { const backToTopBtn = document.getElementById('back-to-top'); if (window.scrollY > 300) { backToTopBtn.style.display = 'block'; } else { backToTopBtn.style.display = 'none'; } }); -
滚动加载(无限滚动):
window.addEventListener('scroll', () => { const { scrollHeight, clientHeight, scrollTop } = document.documentElement; // 当滚动到距离底部100px时加载更多 if (scrollTop + clientHeight >= scrollHeight - 100) { loadMoreData(); } }); -
导航栏样式切换:滚动时改变导航栏背景透明度:
window.addEventListener('scroll', () => { const navbar = document.querySelector('.navbar'); navbar.style.backgroundColor = `rgba(0, 0, 0, ${window.scrollY / 300})`; });
六、问题
1. 问:如何获取移动端的滚动位置?
- 答:
- 移动端浏览器与PC端一致,使用
window.scrollX/Y或pageX/YOffset。 - 需注意:部分移动端浏览器存在“橡皮筋滚动”效果,滚动事件触发可能有延迟。
- 移动端浏览器与PC端一致,使用
2. 问:iframe中的滚动位置如何获取?
- 答:
- 通过
iframe.contentWindow访问其窗口对象:const iframe = document.querySelector('iframe'); const iframeScrollX = iframe.contentWindow.scrollX; - 需注意同源策略限制(非同源iframe无法访问)。
- 通过
3. 问:scrollTo() 和 scrollBy() 的区别?
- 答:
scrollTo(x, y):滚动到指定坐标(绝对位置)。scrollBy(x, y):在当前位置基础上滚动指定偏移量(相对位置)。- 示例:
window.scrollTo(0, 1000); // 滚动到垂直1000px处 window.scrollBy(0, 500); // 再向下滚动500px