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

jQuery分页点击事件多次触发且数据加载缓慢如何解决

问题根因说明

  1. 事件多次触发原因
  • 使用$(document).on事件委托绑定点击事件,如果这段JS代码放在会被动态替换的页面内容中,每次分页加载后都会重复绑定事件,导致一次点击触发多次回调。
  • 没有加请求锁,用户连续点击分页链接会发起多个重复请求。
  • 原代码直接替换整个<body>内容,会导致页面所有资源重新加载,同时内嵌的JS脚本重复执行,进一步加剧事件重复绑定的问题。
  1. 加载耗时长原因
  • 接口返回整个页面的HTML,返回体积大,传输耗时久。
  • 替换整个body导致页面所有静态资源(样式、脚本、图片)重新渲染加载,额外增加耗时。

解决方案

第一步:修改jQuery代码

增加请求锁、事件防重复绑定、只替换列表区域内容:

// 请求锁,避免重复发起请求
let isLoading = false;
// 绑定事件前先解绑之前的同类型事件,彻底解决重复绑定问题
$(document).off('click', '.pagination a').on('click', '.pagination a', function(event) {
  event.preventDefault();
  if (isLoading) return;
  isLoading = true;
  // 增加加载提示,避免用户重复点击
  $('#table_data').html('<p style="text-align:center;padding:20px 0;">加载中...</p>');
  const page = $(this).attr('href').split('page=')[1];
  getData(page);
});

function getData(page) {
  $.ajax({
    url: "pagination?page=" + page,
  }).done(function(res) {
    // 仅替换列表区域内容,不修改页面其他部分
    $('#table_data').html(res);
  }).fail(function() {
    $('#table_data').html('<p style="text-align:center;padding:20px 0;color:#f56c6c;">加载失败,请刷新重试</p>');
  }).always(function() {
    // 请求结束后释放锁
    isLoading = false;
  });
}

第二步:拆分Blade模板

将列表区域的代码单独抽成子模板,减少接口返回的内容体积:

  1. 新建resources/views/posts/post_list.blade.php,内容如下:
@if(count($posts)>0)
    @foreach ($posts as $post)
        <div class="well" >
            <div class="row">
                <div class="col-md-4 col-sm-4">
                    <!-- 增加图片懒加载,优化页面渲染速度 -->
                    <img loading="lazy" style="height:300px; width:400px;" src="/storage/cover_images/{{$post->cover_image}}" alt="{{$post->title}}">
                </div>
                <div class="col-md-8 col-sm-8">
                    <h3><a href="/posts/{{$post->id}}">{{$post->title}}</a></h3>
                    <small>Written on {{$post->created_at}}</small>
                </div>
            </div>
        </div>
    @endforeach
    {{$posts->links()}}
@else
    <p>No Post Found</p>
@endif
  1. 修改index.blade.php代码,修正原来的标签嵌套错误,引入子模板:
@extends('layouts.app')

@section('content')
<!-- 修正原代码h1开标签对应h3关标签的错误 -->
<h1>Post</h1>
  
<div id="table_data">
    @include('posts.post_list')
</div>
@endsection

第三步:修改后端控制器逻辑

判断请求类型,AJAX请求只返回子模板内容:

use Illuminate\Http\Request;

public function index(Request $request)
{
    // 原有分页查询逻辑保持不变
    $posts = \App\Models\Post::paginate(10);
    
    // 识别AJAX请求,仅返回列表部分的HTML
    if ($request->ajax()) {
        return view('posts.post_list', compact('posts'))->render();
    }
    
    // 普通页面请求返回完整页面
    return view('posts.index', compact('posts'));
}

额外优化建议

  • 可以给加载中的分页链接增加disabled样式,进一步避免用户误点。
  • 封面图片可以提前做压缩处理,减少图片加载耗时。
  • 把jQuery绑定事件的代码放到app.blade.php的底部,不要放在index.blade.php中,从根源避免重复加载执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 04:27:02