📜移动端上拉加载 & 下拉刷新实现方案(原生 JS / Vue / React / jQuery / Angular)
🎉一、实现原理概述
移动端的 上拉加载 和 下拉刷新 是常见的交互功能,其核心是监听滚动事件或手势滑动事件,并判断用户是否触发了“上拉”或“下拉”的动作。
核心逻辑:
- 下拉刷新:用户从顶部下拉,触发数据重新加载。
- 上拉加载:用户滚动到底部附近,触发分页加载更多数据。
🛠️二、通用实现思路(适用于所有技术栈)
✅ 实现步骤(原生 JS 思路):
1. 获取容器元素
参数:
container:表示滚动容器元素,可以是整个页面窗口(window)或某个特定的DOM元素。
实现思路:
- 使用
document.querySelector或document.getElementById获取特定的滚动容器。 - 如果是整个页面,可以直接使用
window。
const container = document.querySelector('.scroll-container'); // 或者 window;
2. 监听滚动事件
参数:
event:滚动事件对象,包含滚动相关的信息。
实现思路:
- 使用
addEventListener监听滚动事件。 - 如果监听的是
window,直接使用window.addEventListener('scroll', handler)。 - 如果是自定义容器,监听容器的滚动事件。
container.addEventListener('scroll', handleScroll);
3. 判断是否到达底部(上拉加载)
参数:
scrollTop:滚动容器当前滚动的距离。clientHeight:滚动容器的可视高度。scrollHeight:滚动容器内容的总高度。threshold:触发加载的阈值,通常设置为50到100像素。
实现思路:
- 使用公式
scrollTop + clientHeight >= scrollHeight - threshold判断是否接近底部。 - 触发加载更多数据的逻辑。
function handleScroll(event) {
const scrollTop = container.scrollTop;
const clientHeight = container.clientHeight;
const scrollHeight = container.scrollHeight;
const threshold = 50;
if (scrollTop + clientHeight >= scrollHeight - threshold) {
loadMoreContent();
}
}
4. 判断是否下拉(下拉刷新)
参数:
startY:触摸开始的Y坐标。currentY:当前触摸的Y坐标。pullDownDistance:下拉的距离,用于判断是否达到刷新条件。
实现思路:
- 监听
touchstart和touchmove事件。 - 记录初始触摸点
startY,在touchmove时计算currentY - startY,判断是否下拉。
let startY = 0;
container.addEventListener('touchstart', (event) => {
startY = event.touches[0].clientY;
});
container.addEventListener('touchmove', (event) => {
const currentY = event.touches[0].clientY;
const pullDownDistance = currentY - startY;
if (pullDownDistance > 50) {
// 假设下拉50像素触发刷新
refreshContent();
}
});
5. 防抖与节流控制
参数:
delay:防抖或节流的延迟时间,通常设置为200到500毫秒。
实现思路:
- 使用
setTimeout实现防抖,确保在滚动停止后延迟执行。 - 使用
lodash.throttle或自定义节流函数控制触发频率。
function debounce(func, delay) {
let timeoutId;
return function() {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(this, arguments), delay);
};
}
const throttledScrollHandler = debounce(handleScroll, 300);
container.addEventListener('scroll', throttledScrollHandler);
6. 加载状态管理
参数:
isLoading:布尔值,表示是否正在加载数据。loadingElement:表示加载动画的DOM元素。
实现思路:
- 在加载数据时,显示加载动画并设置
isLoading为true。 - 数据加载完成后,隐藏加载动画并设置
isLoading为false。
let isLoading = false;
const loadingElement = document.querySelector('.loading-animation');
function loadMoreContent() {
if (isLoading) return;
isLoading = true;
loadingElement.style.display = 'block';
// 模拟异步加载
setTimeout(() => {
// 加载数据
isLoading = false;
loadingElement.style.display = 'none';
}, 1000);
}
7. 数据加载完成后更新视图
参数:
newData:新加载的数据。
实现思路:
- 在数据加载完成后,将新数据追加到现有数据中。
- 更新DOM以反映新数据。
function updateView(newData) {
const contentElement = document.querySelector('.content');
newData.forEach(item => {
const element = document.createElement('div');
element.textContent = item.title;
contentElement.appendChild(element);
});
}
8. 异常处理
参数:
retryCount:重试次数。maxRetries:最大重试次数。
实现思路:
- 在数据加载失败时,显示错误信息。
- 提供重试按钮或自动重试机制。
function loadMoreContent() {
if (isLoading) return;
isLoading = true;
loadingElement.style.display = 'block';
fetchData()
.then(data => {
updateView(data);
isLoading = false;
loadingElement.style.display = 'none';
})
.catch(error => {
console.error('Failed to load data:', error);
isLoading = false;
loadingElement.style.display = 'none';
// 显示错误信息
});
}
🧩三、原生 JavaScript 实现代码(完整示例)
下面是老曹添加了详细注释的完整代码,解释了每一行代码的功能和作用:
<div id="container" style="height: 100vh; overflow-y: scroll;">
<div id="refreshIndicator" class="refresh-indicator">下拉刷新</div>
<ul id="list">
<!-- 列表项动态插入 -->
</ul>
<div id="loading" class="loading">加载中...</div>
</div>
<script>
// 获取DOM元素
const container = document.getElementById('container'); // 滚动容器
const list = document.getElementById('list'); // 列表容器
const refreshIndicator = document.getElementById('refreshIndicator'); // 下拉刷新指示器
const loading = document.getElementById('loading'); // 加载中指示器
// 初始化状态变量
let isRefreshing = false; // 是否正在刷新
let isLoadin

&spm=1001.2101.3001.5002&articleId=148775980&d=1&t=3&u=3a4de23e6c934e299f9a023cabcb4389)
2587

被折叠的 条评论
为什么被折叠?



