获得滚动条的滚动距离
一个用于获取滚动位置的工具函数,当前版本只能获取窗口的滚动偏移量,可以同时支持窗口和特定dom元素的滚动位置获取。
代码如下:
function getScrollOffset(element) {
// 如果不传参数或传入window,获取窗口滚动位置
if (!element || element === window) {
if (window.pageXOffset !== undefined) {
return {
x: window.pageXOffset,
y: window.pageYOffset
};
} else {
return {
x: Math.max(document.body.scrollLeft, document.documentElement.scrollLeft),
y: Math.max(document.body.scrollTop, document.documentElement.scrollTop)
};
}
}
// 如果传入DOM元素,获取元素的滚动位置
if (element && element.nodeType === 1) {
return {
x: element.scrollLeft,
y: element.scrollTop
};
}
// 参数错误处理
console.warn('getScrollOffset: 参数必须是DOM元素或window');
return { x: 0, y: 0 };
}使用场景
1. 获取窗口滚动位置
// 不传参数或传入window
var windowScroll = getScrollOffset();
// 或
var windowScroll = getScrollOffset(window);
console.log('窗口滚动位置:', windowScroll.x, windowScroll.y);
// 滚动到顶部检测
function isAtTop() {
var scroll = getScrollOffset();
return scroll.y === 0;
}
// 滚动到底部检测
function isAtBottom() {
var scroll = getScrollOffset();
var pageHeight = Math.max(
document.body.scrollHeight,
document.documentElement.scrollHeight
);
var viewportHeight = window.innerHeight;
return scroll.y + viewportHeight >= pageHeight;
}2. 获取特定元素滚动位置
// 获取可滚动容器的滚动位置
var scrollableDiv = document.getElementById('scroll-container');
var containerScroll = getScrollOffset(scrollableDiv);
console.log('容器滚动位置:', containerScroll.x, containerScroll.y);
// 检查元素是否滚动到底部
function isContainerAtBottom(container) {
var scroll = getScrollOffset(container);
return scroll.y >= container.scrollHeight - container.clientHeight;
}
// 滚动到指定元素内部位置
function scrollToPosition(container, x, y) {
container.scrollLeft = x;
container.scrollTop = y;
// 验证滚动结果
var currentScroll = getScrollOffset(container);
console.log('当前滚动位置:', currentScroll.x, currentScroll.y);
}3. 滚动事件监听
// 监听窗口滚动
function createWindowScrollHandler() {
var lastScrollY = 0;
return function() {
var currentScroll = getScrollOffset();
// 检测滚动方向
var direction = currentScroll.y > lastScrollY ? 'down' : 'up';
// 执行滚动相关逻辑
handleScrollDirection(direction, currentScroll);
lastScrollY = currentScroll.y;
};
}
// 监听元素滚动
function monitorElementScroll(element, callback) {
var lastScroll = getScrollOffset(element);
element.addEventListener('scroll', function() {
var currentScroll = getScrollOffset(element);
var deltaX = currentScroll.x - lastScroll.x;
var deltaY = currentScroll.y - lastScroll.y;
callback(currentScroll, deltaX, deltaY);
lastScroll = currentScroll;
});
}4. 无限滚动加载
function setupInfiniteScroll(container, loadMoreCallback, threshold = 100) {
monitorElementScroll(container, function(scroll, deltaX, deltaY) {
var maxScrollY = container.scrollHeight - container.clientHeight;
var distanceFromBottom = maxScrollY - scroll.y;
// 接近底部时触发加载
if (distanceFromBottom < threshold) {
loadMoreCallback();
}
});
}
// 使用示例
var chatContainer = document.getElementById('chat-messages');
setupInfiniteScroll(chatContainer, function() {
console.log('加载更多消息...');
// 加载更多数据的逻辑
});5. 滚动进度指示器
function createScrollProgress(container) {
var progressBar = document.createElement('div');
progressBar.style.cssText = `
position: sticky;
top: 0;
height: 3px;
background: linear-gradient(90deg, #ff6b6b, #4ecdc4);
width: 0%;
transition: width 0.1s;
z-index: 1000;
`;
if (container === window) {
document.body.appendChild(progressBar);
} else {
container.parentNode.insertBefore(progressBar, container);
}
function updateProgress() {
var scroll = getScrollOffset(container);
var maxScroll, currentProgress;
if (container === window) {
maxScroll = Math.max(
document.body.scrollHeight,
document.documentElement.scrollHeight
) - window.innerHeight;
currentProgress = (scroll.y / maxScroll) * 100;
} else {
maxScroll = container.scrollHeight - container.clientHeight;
currentProgress = maxScroll > 0 ? (scroll.y / maxScroll) * 100 : 0;
}
progressBar.style.width = Math.min(100, Math.max(0, currentProgress)) + '%';
}
// 监听滚动
if (container === window) {
window.addEventListener('scroll', updateProgress);
} else {
container.addEventListener('scroll', updateProgress);
}
updateProgress(); // 初始更新
}本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!