📜 滚动优化
移动端滚动体验直接影响用户感知,主要涉及平滑滚动、惯性滚动、下拉刷新、滚动穿透等问题。
iOS 惯性滚动(橡皮筋效果)
/* ===== 开启 iOS 平滑惯性滚动 ===== */
.scroll-container {
overflow-y: auto;
-webkit-overflow-scrolling: touch; /* iOS 惯性滚动 */
/* 注意:该属性在 iOS 13+ 已自动支持,旧版需手动添加 */
}
/* 隐藏滚动条但保留滚动功能 */
.scroll-hidden {
overflow-y: auto;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE */
}
.scroll-hidden::-webkit-scrollbar {
display: none; /* Chrome / Safari */
}
滚动穿透问题
当弹窗/遮罩层打开时,背景页面仍可滚动。
// ===== 解决滚动穿透 =====
// 方式一:body 固定(最常用)
function preventScrollThrough(isOpen) {
if (isOpen) {
const scrollY = window.scrollY;
document.body.style.position = 'fixed';
document.body.style.top = `-${scrollY}px`;
document.body.style.width = '100%';
} else {
const scrollY = document.body.style.top;
document.body.style.position = '';
document.body.style.top = '';
document.body.style.width = '';
window.scrollTo(0, parseInt(scrollY || '0') * -1);
}
}
// 方式二:弹窗内阻止 touchmove 冒泡
modal.addEventListener('touchmove', (e) => {
e.stopPropagation(); // 阻止事件冒泡到背景
}, { passive: false });
// 方式三:CSS overscroll-behavior
.modal-scroll {
overscroll-behavior: contain; /* 滚动边界不传递到父元素 */
}
下拉刷新与上拉加载
// ===== 下拉刷新 & 上拉加载更多 =====
let startY = 0;
let isLoading = false;
// 下拉刷新检测
document.addEventListener('touchstart', (e) => {
startY = e.touches[0].clientY;
}, { passive: true });
document.addEventListener('touchmove', (e) => {
if (window.scrollY === 0) {
const deltaY = e.touches[0].clientY - startY;
if (deltaY > 60 && !isLoading) {
console.log('🔄 触发下拉刷新');
// refreshData();
}
}
}, { passive: true });
// 上拉加载更多(滚动到底部检测)
window.addEventListener('scroll', () => {
const { scrollTop, scrollHeight, clientHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - 100) {
if (!isLoading) {
console.log('📄 触发加载更多');
// loadMore();
}
}
}, { passive: true });