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

CodeIgniter带筛选的Ajax无限滚动数据重复问题求助

解决CodeIgniter无限滚动+筛选时数据重复的问题

兄弟,我太懂这种重复加载数据的糟心感了——之前做电商商品列表页的时候,也踩过一模一样的坑!咱们一步步拆解问题,搞定它:

核心问题分析

你现在的情况是:点击筛选能生效、分页单独用没问题,但滚动加载时重复出现数据,大概率是这几个原因:

  • 筛选条件变化后,分页的起始偏移量没重置,导致滚动时从旧的位置继续加载新筛选后的数据集
  • 滚动事件触发太频繁,导致重复发送相同请求
  • 每次滚动加载时,没有同步最新的筛选条件到后端

具体解决方案

1. 重构前端JS逻辑,统一管理分页状态和筛选条件

把分页偏移量、加载状态、筛选条件的获取逻辑抽出来,确保每次加载都用最新的状态:

$(document).ready(function() {
    // 全局变量存储分页核心状态
    let currentOffset = 0;
    const perPage = <?php echo $per_page; ?>; // 从后端传递每页加载数量
    let isLoading = false; // 防止重复请求的锁

    // 初始化加载第一页
    loadContent();

    // 筛选条件变化时:重置分页+清空现有内容+重新加载
    $('input[name="brand"]').on('change', function() {
        currentOffset = 0;
        $('#content-container').empty(); // 清空旧内容
        $('#load-more-tip').text('加载中...');
        loadContent();
    });

    // 滚动触发加载的逻辑
    $(window).scroll(function() {
        // 滚动到距离底部100px以内,且当前没有加载请求时触发
        if($(window).scrollTop() + $(window).height() >= $(document).height() - 100 && !isLoading) {
            loadContent();
        }
    });

    // 核心加载函数
    function loadContent() {
        isLoading = true;
        // 实时获取最新的选中品牌(复选框值)
        const selectedBrands = $('input[name="brand"]:checked').map(function() {
            return $(this).val();
        }).get().join(','); // 转成逗号分隔的字符串方便后端处理

        $.ajax({
            url: '<?php echo site_url("your_controller/load_more_data"); ?>',
            type: 'POST',
            data: {
                offset: currentOffset,
                per_page: perPage,
                brand: selectedBrands
            },
            success: function(response) {
                const res = JSON.parse(response);
                if(res.html.length > 0) {
                    // 追加新内容到容器
                    $('#content-container').append(res.html);
                    currentOffset += perPage; // 更新偏移量
                    $('#load-more-tip').text('滚动加载更多');
                } else {
                    $('#load-more-tip').text('没有更多数据了');
                }
                isLoading = false;
            },
            error: function() {
                isLoading = false;
                $('#load-more-tip').text('加载失败,请重试');
            }
        });
    }
});

2. 调整后端CodeIgniter控制器逻辑

确保后端能正确接收筛选条件和分页参数,返回对应的数据片段:

public function load_more_data() {
    // 获取前端传递的参数
    $offset = $this->input->post('offset') ?? 0;
    $per_page = $this->input->post('per_page') ?? 10;
    $brand_str = $this->input->post('brand') ?? '';

    // 构建查询条件
    $this->db->select('*');
    $this->db->from('your_product_table');
    
    // 处理品牌筛选
    if(!empty($brand_str)) {
        $brand_list = explode(',', $brand_str);
        $this->db->where_in('brand', $brand_list);
    }

    // 应用分页
    $this->db->limit($per_page, $offset);
    $query = $this->db->get();
    $products = $query->result();

    // 拼接要返回的HTML片段
    $html = '';
    foreach($products as $item) {
        $html .= '<div class="product-card">';
        $html .= '<h3>'.$item->product_name.'</h3>';
        $html .= '<p>品牌:'.$item->brand.'</p>';
        $html .= '</div>';
    }

    // 返回JSON格式数据
    echo json_encode(['html' => $html]);
}

3. 关键注意点

  • 筛选后必须重置偏移量:只要复选框状态变化,就把currentOffset设为0,同时清空现有内容,避免新旧数据混合
  • 添加加载锁isLoading:防止滚动时短时间内重复发送请求,导致相同偏移量的数据被加载多次
  • 实时获取筛选条件:每次调用loadContent时都重新抓取选中的复选框值,确保传给后端的是最新的筛选条件
  • 不要依赖页面初始化时的总数据量:原来的total_groups是页面加载时的总条数,筛选后总数据量会变化,直接通过返回的HTML长度判断是否还有更多数据更可靠

按照这个思路改完,应该就能解决重复加载的问题了,如果还有细节问题(比如筛选条件的格式、后端查询的逻辑),再微调下就行!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:55:09