js实现下拉加载更多
实现下拉加载更多的核心逻辑
监听滚动事件判断是否到达页面底部,触发数据加载。需要结合scrollTop、clientHeight和scrollHeight三个属性进行计算。
window.addEventListener('scroll', function() {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
const clientHeight = document.documentElement.clientHeight;
const scrollHeight = document.documentElement.scrollHeight;
if (scrollTop + clientHeight >= scrollHeight - 10) {
loadMoreData();
}
});
数据加载函数实现
创建异步数据加载函数,通常需要配合分页参数和防抖处理。
let isLoading = false;
let page = 1;
async function loadMoreData() {
if (isLoading) return;
isLoading = true;
try {
const newData = await fetchData(page);
renderData(newData);
page++;
} catch (error) {
console.error('加载失败:', error);
} finally {
isLoading = false;
}
}
性能优化方案
添加防抖函数避免频繁触发,设置合理的阈值减少误触发。
function debounce(func, delay) {
let timer;
return function() {
clearTimeout(timer);
timer = setTimeout(func, delay);
};
}
const checkScroll = debounce(() => {
const scrollThreshold = 100;
const { scrollTop, clientHeight, scrollHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - scrollThreshold) {
loadMoreData();
}
}, 200);
window.addEventListener('scroll', checkScroll);
完整组件示例
结合HTML结构的完整实现示例,包含加载状态提示。
class InfiniteScroll {
constructor(container, loader, options = {}) {
this.container = container;
this.loader = loader;
this.threshold = options.threshold || 100;
this.page = 1;
this.isLoading = false;
this.init();
}
init() {
window.addEventListener('scroll', this.checkScroll.bind(this));
}
async checkScroll() {
const { scrollTop, clientHeight, scrollHeight } = document.documentElement;
const shouldLoad = scrollTop + clientHeight >= scrollHeight - this.threshold;
if (shouldLoad && !this.isLoading) {
this.isLoading = true;
this.loader.style.display = 'block';
try {
const items = await this.fetchItems(this.page);
this.appendItems(items);
this.page++;
} finally {
this.isLoading = false;
this.loader.style.display = 'none';
}
}
}
async fetchItems(page) {
// 实际项目中替换为API调用
return mockFetch(page);
}
appendItems(items) {
const fragment = document.createDocumentFragment();
items.forEach(item => {
const element = document.createElement('div');
element.textContent = item;
fragment.appendChild(element);
});
this.container.appendChild(fragment);
}
}
注意事项
滚动事件监听会频繁触发,必须做好性能优化。移动端需要考虑touch事件兼容性。
数据加载需要处理错误情况,显示适当的用户反馈。当没有更多数据时应当移除滚动监听。
分页参数需要与服务端API保持一致,确保每次请求返回正确的数据片段。







