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
相关产品推荐
相关产品推荐

