You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用jQuery Ajax异步分批加载Laravel博客的数据库帖子?

我来帮你搞定Laravel博客的分批加载(无限滚动)功能!结合你用jQuery Ajax的需求,分后端和前端两部分来实现,代码都给你写清楚:

Laravel + jQuery Ajax 实现帖子分批加载(无限滚动)

一、后端控制器修改

首先要把原来一次性获取所有帖子的逻辑改成分页查询,并且区分Ajax请求和首次页面请求:

public function index()
{
    // 按创建时间倒序排列,每页加载10条(可根据你的需求调整数量)
    $posts = DB::table('posts')->orderBy('created_at', 'desc')->paginate(10);
    
    // 判断是否为Ajax请求:如果是,返回渲染好的帖子片段和下一页链接
    if(request()->ajax()) {
        // 渲染帖子列表的部分视图(需要新建这个视图文件)
        $postHtml = view('posts.partials.post-list', compact('posts'))->render();
        return response()->json([
            'html' => $postHtml,
            'next_page_url' => $posts->nextPageUrl() // Laravel分页自带的下一页链接
        ]);
    }
    
    // 首次访问主页时,返回完整的主页视图
    return view('home', compact('posts'));
}

二、前端视图结构

你需要两个视图文件:一个是主页视图,一个是帖子列表的部分视图(用来复用渲染帖子)

1. 主页视图(home.blade.php)

<!DOCTYPE html>
<html>
<head>
    <title>我的博客</title>
    <!-- 引入jQuery,确保路径正确 -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <style>
        .post-card {
            border: 1px solid #eee;
            padding: 15px;
            margin-bottom: 10px;
            border-radius: 4px;
        }
        .loading {
            text-align: center;
            padding: 20px;
            color: #666;
        }
    </style>
</head>
<body>
    <div class="posts-container">
        <!-- 初始加载的帖子列表,引入部分视图 -->
        @include('posts.partials.post-list')
    </div>

    <!-- 加载提示,初始隐藏 -->
    <div class="loading" style="display: none;">加载中...</div>

    <!-- 下面放Ajax滚动加载的脚本 -->
    <script>
        // 这里写Ajax逻辑,见下一部分
    </script>
</body>
</html>

2. 帖子列表部分视图(posts/partials/post-list.blade.php)

这个视图用来循环渲染单条帖子,方便后端Ajax请求时只返回帖子内容:

@foreach($posts as $post)
    <div class="post-card">
        <h3>{{ $post->title }}</h3>
        <p>{{ Str::limit($post->content, 200) }}</p> <!-- 可选:截断长内容 -->
        <span class="post-date">{{ $post->created_at->format('Y-m-d H:i') }}</span>
    </div>
@endforeach

三、jQuery Ajax滚动加载逻辑

把这段脚本放到主页视图的<script>标签里:

$(document).ready(function() {
    // 初始化下一页链接(从Laravel分页对象获取)
    let nextPageUrl = '{{ $posts->nextPageUrl() }}';
    // 加载状态锁,防止重复请求
    let isLoading = false;

    // 监听页面滚动事件
    $(window).scroll(function() {
        // 触发条件:滚动到距离底部100px以内,且不在加载中,还有下一页
        if (
            $(window).scrollTop() + $(window).height() >= $(document).height() - 100 &&
            !isLoading &&
            nextPageUrl
        ) {
            isLoading = true;
            $('.loading').show();

            // 发送Ajax请求
            $.ajax({
                url: nextPageUrl,
                type: 'GET',
                dataType: 'json',
                success: function(response) {
                    // 将新帖子追加到容器中
                    $('.posts-container').append(response.html);
                    // 更新下一页链接
                    nextPageUrl = response.next_page_url;
                    // 隐藏加载提示,解锁加载状态
                    $('.loading').hide();
                    isLoading = false;

                    // 如果没有下一页了,提示并取消滚动监听
                    if (!nextPageUrl) {
                        $(window).off('scroll');
                        $('.loading').text('没有更多帖子啦').show();
                    }
                },
                error: function() {
                    $('.loading').text('加载失败,点击重试').show();
                    isLoading = false;
                    // 可选:点击重试
                    $('.loading').one('click', function() {
                        $(this).text('加载中...');
                        $(window).trigger('scroll');
                    });
                }
            });
        }
    });
});

四、关键注意点

  • 确保你的posts表有created_at字段(Laravel默认迁移会生成),用来排序帖子
  • 分页数量paginate(10)可以根据你的帖子高度调整,让滚动体验更自然
  • 如果滚动事件触发太频繁,可以用节流函数优化(比如引入Lodash的_.throttle)
  • 样式可以根据你的博客风格自定义,比如给加载提示加个 spinner 动画

内容的提问来源于stack exchange,提问作者Deeven

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:50:59