js实现下拉加载更多
实现下拉加载更多的核心逻辑
监听滚动事件,判断是否滚动到页面底部。滚动到底部时触发数据加载函数,获取新数据并渲染到页面。
// 获取需要监听的容器元素
const container = document.getElementById('container');
// 当前加载的页码
let currentPage = 1;
// 是否正在加载数据
let isLoading = false;
// 滚动事件处理函数
container.addEventListener('scroll', function() {
// 判断是否滚动到底部
if (container.scrollTop + container.clientHeight >= container.scrollHeight - 10 && !isLoading) {
loadMoreData();
}
});
// 加载更多数据
function loadMoreData() {
isLoading = true;
// 显示加载状态
const loadingElement = document.createElement('div');
loadingElement.textContent = '加载中...';
container.appendChild(loadingElement);
// 模拟API请求
fetch(`/api/data?page=${currentPage}`)
.then(response => response.json())
.then(data => {
// 移除加载状态
container.removeChild(loadingElement);
// 渲染新数据
renderData(data);
// 更新页码
currentPage++;
isLoading = false;
})
.catch(error => {
console.error('加载失败:', error);
container.removeChild(loadingElement);
isLoading = false;
});
}
优化性能的实现方式
使用Intersection Observer API替代滚动事件监听,性能更好且更精确。
const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting && !isLoading) {
loadMoreData();
}
}, {
root: document.getElementById('container'),
threshold: 1.0
});
// 观察底部元素
const sentinel = document.createElement('div');
container.appendChild(sentinel);
observer.observe(sentinel);
完整实现示例
结合上述两种方法,提供完整的下拉加载实现。
class InfiniteScroll {
constructor(container, loader, callback) {
this.container = container;
this.loader = loader;
this.callback = callback;
this.page = 1;
this.loading = false;
this.observer = null;
this.init();
}
init() {
this.sentinel = document.createElement('div');
this.container.appendChild(this.sentinel);
this.observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting && !this.loading) {
this.loadMore();
}
}, {
root: this.container,
threshold: 1.0
});
this.observer.observe(this.sentinel);
}
loadMore() {
this.loading = true;
this.loader.style.display = 'block';
this.callback(this.page).then(() => {
this.page++;
this.loading = false;
this.loader.style.display = 'none';
}).catch(() => {
this.loading = false;
this.loader.style.display = 'none';
});
}
}
// 使用示例
const scroll = new InfiniteScroll(
document.getElementById('container'),
document.getElementById('loader'),
(page) => {
return fetch(`/api/data?page=${page}`)
.then(res => res.json())
.then(data => {
// 渲染数据
renderData(data);
});
}
);
注意事项
确保在数据加载完成前不会重复触发加载函数,避免多次请求。可以在加载函数开始时设置标志位,完成后重置。
处理网络请求错误情况,提供重试机制或错误提示。错误处理应该重置加载状态,允许用户再次尝试。
移动端需要考虑触摸事件的兼容性,确保在各种设备上都能正常触发加载。可以适当调整触发阈值,避免过于敏感或迟钝。

对于大量数据渲染,考虑使用虚拟滚动技术优化性能。只渲染可视区域内的元素,减少DOM节点数量。






