CodeIgniter3结合jQuery Ajax实现文章懒加载返回整页问题求解
问题原因及解决方案
核心错误点
- 你的AJAX请求直接调用了
Posts控制器的index()方法,这个方法默认就是渲染完整的页面布局(themes/{$data['theme_directory']}/layout),没有针对异步请求做单独处理,自然会返回完整HTML内容。 - 额外逻辑问题:你把AJAX请求的
type设置为POST,但分页参数page是拼接在URL的GET参数中,虽然CodeIgniter也能读取到参数,但逻辑不统一,还可能触发框架的CSRF校验导致请求失败。
修复步骤
1. 控制器端适配AJAX请求
修改application\controllers\Posts.php的index()方法,增加AJAX请求判断,异步请求时只返回文章列表的HTML片段而非完整页面:
public function index() { //call initialization method $config = $this->_initPagination("/", $this->Posts_model->get_num_rows()); $data = $this->Static_model->get_static_data(); $data['base_url'] = base_url("/"); $data['pages'] = $this->Pages_model->get_pages(); $data['categories'] = $this->Categories_model->get_categories(); $data['search_errors'] = validation_errors(); //use limit and offset returned by _initPaginator method $data['posts'] = $this->Posts_model->get_posts($config['limit'], $config['offset']); // 新增:判断是否为AJAX请求,是则直接渲染文章列表片段返回 if ($this->input->is_ajax_request()) { // 你需要把现有的文章列表部分抽成单独的twig模板,比如post_list.twig echo $this->twig->render("themes/{$data['theme_directory']}/partials/post_list.twig", $data); exit; } // 非AJAX请求走原来的完整页面渲染逻辑 $this->twig->addGlobal('pagination', $this->pagination->create_links()); // featured posts if ($data['is_featured']) { $data['featured'] = $this->Posts_model->featured_posts(); $this->twig->addGlobal('featuredPosts', "themes/{$data['theme_directory']}/partials/hero.twig"); } $this->twig->display("themes/{$data['theme_directory']}/layout", $data); }
2. 拆分文章列表模板
把原来布局模板里#postsContainer内部的文章循环逻辑,单独抽成themes/你的主题目录/partials/post_list.twig文件,内容就是循环输出post-preview结构的代码。
3. 修复前端AJAX逻辑
统一请求方式,同时增加加载锁防止滚动时重复触发请求:
(function($) { var currentPage = 2; // 第一页已经在页面初始化时渲染了,直接从第二页开始加载 var isLoading = false; // 加载锁,避免重复请求 // 隐藏分页 $('.pagination').hide(); $(window).scroll(function() { if (!isLoading && $(window).scrollTop() >= $(document).height() - $(window).height() - 10) { loadMore(); } }); function loadMore() { isLoading = true; $.ajax({ url: baseUrl, type: 'GET', // 统一用GET传递分页参数,和原有分页逻辑一致 data: {page: currentPage}, beforeSend: function() { $('.loader').show(); } }) .done(function(data) { $('.loader').hide(); // 没有更多数据就停止加载 if (data.trim() == '') { $(window).off('scroll'); return; } $("#postsContainer").append(data); currentPage++; isLoading = false; }); } })(jQuery);
内容的提问来源于stack exchange,提问作者Razvan Zamfir
相关产品推荐
相关产品推荐

