滚动至页面底部时,用AJAX+JSON加载页面的最佳方案(Laravel5.6场景)
嘿,这个滚动加载的需求我之前在做类似社交平台的时候实现过,给你一套靠谱的方案,分后端微调+前端实现两部分来讲,都是基于你现有的代码来改的:
实现滚动加载的最佳方案
一、后端(Laravel)微调
你现有的代码已经差不多了,只需要修正一个小细节——Laravel模型类名是首字母大写的,把post改成Post避免报错,调整后的控制器代码:
public function view_post(){ $post = Post::orderBy('created_at', 'desc')->paginate(5); return response()->json([ 'posts' => $post ]); }
这个接口返回的JSON里已经自带了current_page(当前页)、last_page(最后一页)这些分页关键数据,正好用来判断是否还有更多内容可以加载。
二、前端AJAX+滚动监听实现
我用jQuery来写示例(毕竟大部分Laravel项目都会引入它),如果用原生JS逻辑也是一样的:
1. 基础HTML结构
先准备好帖子容器和加载提示:
<div id="posts-container"> <!-- 这里会渲染加载出来的帖子内容 --> </div> <div id="loading" style="text-align:center; padding:1rem; display:none;">正在加载更多...</div>
2. 核心JS逻辑
先定义几个控制变量,然后写加载函数和滚动监听:
// 初始化控制变量 let currentPage = 1; let isLoading = false; let lastPage = 0; // 第一次请求后会更新这个值 // 加载更多帖子的函数 function loadMorePosts() { // 防止重复请求,或者已经加载完所有内容时直接返回 if (isLoading || currentPage >= lastPage) return; isLoading = true; $('#loading').show(); // 发送AJAX请求 $.ajax({ url: '/get-post', type: 'GET', data: { page: currentPage + 1 }, // 传递下一页的页码参数 success: function(response) { // 更新当前页和最后一页的值 currentPage = response.posts.current_page; lastPage = response.posts.last_page; // 把新帖子渲染到容器里(这里的HTML结构你可以根据自己的需求调整) response.posts.data.forEach(post => { const postItem = ` <div class="post-card" style="border:1px solid #eee; padding:1rem; margin-bottom:1rem;"> <h4>${post.title}</h4> <p>${post.content}</p> <small class="text-muted">发布于 ${post.created_at}</small> </div> `; $('#posts-container').append(postItem); }); $('#loading').hide(); isLoading = false; // 如果已经加载到最后一页,提示用户没有更多内容了 if (currentPage >= lastPage) { $('#loading').html('没有更多帖子啦~').show(); } }, error: function() { $('#loading').hide(); isLoading = false; alert('加载失败,请稍后再试'); } }); } // 页面加载完成后先加载第一页 $(document).ready(function() { // 先请求第一页数据 $.ajax({ url: '/get-post', type: 'GET', data: { page: 1 }, success: function(response) { currentPage = response.posts.current_page; lastPage = response.posts.last_page; // 渲染第一页帖子 response.posts.data.forEach(post => { const postItem = ` <div class="post-card" style="border:1px solid #eee; padding:1rem; margin-bottom:1rem;"> <h4>${post.title}</h4> <p>${post.content}</p> <small class="text-muted">发布于 ${post.created_at}</small> </div> `; $('#posts-container').append(postItem); }); } }); // 添加滚动监听事件 $(window).scroll(function() { // 当滚动到距离页面底部200px时触发加载(可以根据需求调整这个阈值) if ($(window).scrollTop() + $(window).height() >= $(document).height() - 200) { loadMorePosts(); } }); });
三、几个关键优化点
- 防抖处理:滚动事件会频繁触发,给它加个防抖可以避免不必要的请求,修改滚动监听部分:
let scrollTimer; $(window).scroll(function() { clearTimeout(scrollTimer); scrollTimer = setTimeout(function() { if ($(window).scrollTop() + $(window).height() >= $(document).height() - 200) { loadMorePosts(); } }, 200); // 延迟200ms执行,减少请求频率 });
- 样式优化:把加载提示换成旋转的加载图标会更友好,比如用CSS写个简单的加载动画,替代纯文本提示。
- 移动端兼容:移动端的滚动行为可能有差异,测试时可以结合
touchend事件,但上面的滚动监听在大部分移动端浏览器里也能正常工作。
内容的提问来源于stack exchange,提问作者hamzaerdem
相关产品推荐
相关产品推荐

