下面我将为你提供一个完整、详细、可直接使用的教程,涵盖了前端和后端的修改。

实现原理
下拉加载的核心逻辑是:
-
前端 (HTML/JS):
- 监听页面的滚动事件,当用户滚动到页面底部附近时,触发一个加载函数。
- 这个函数会通过 AJAX 请求,向服务器请求下一页的数据。
- 服务器返回新的数据(通常是 HTML 片段)后,前端将其动态地追加到现有内容的末尾。
- 如果服务器返回的数据为空(表示没有更多内容了),则显示“没有更多了”的提示,并停止监听滚动事件。
-
后端 (PHP/Dede):
- 创建一个专门用于 AJAX 请求的 PHP 文件。
- 这个文件接收前端传来的页码参数 (
page)。 - 它使用 DedeCMS 的分页函数
GetPageList()获取指定页码的数据列表。 - 将获取到的数据循环渲染成 HTML 片段,然后返回给前端。
详细步骤
假设我们要在列表页(如 /plus/list.php?tid=1)实现这个功能。

第一步:修改列表页模板文件 (list_article.htm)
我们需要在模板中引入 jQuery,并添加必要的 HTML 结构和 JavaScript 代码。
-
找到你的列表模板文件: 通常位于
/templets/你的模板名称/list_article.htm。 -
在
<head>标签内引入 jQuery: 如果你的模板没有引入 jQuery,需要先引入,推荐使用 CDN 链接,速度快且稳定。<head> <meta charset="utf-8"> <title>{dede:field.title/}</title> <!-- 引入 jQuery --> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <!-- 其他样式和脚本... --> </head> -
列表区域: 找到
{dede:list}标签包裹的内容列表部分,用一个div包裹起来,并给这个div一个id,方便 JS 操作。修改前 (大致结构):
<ul class="list"> {dede:list pagesize='10'} <li> <a href="[field:arcurl/]">[field:title/]</a> <span>[field:pubdate function="MyDate('Y-m-d',@me)"/]</span> </li> {/dede:list} </ul> <!-- 分页条 --> <div class="dede_pages"> <ul>{dede:pagelist listitem='pre,next,end,option'/}</ul> </div>修改后 (添加了
id和加载提示):<div class="article-list" id="article-list"> {dede:list pagesize='10'} <li> <a href="[field:arcurl/]">[field:title/]</a> <span>[field:pubdate function="MyDate('Y-m-d',@me)"/]</span> </li> {/dede:list} </div> <!-- 原有的分页条可以保留,但会被隐藏,或者你也可以直接删除它 --> <div class="dede_pages" id="pagination" style="display:none;"> <ul>{dede:pagelist listitem='pre,next,end,option'/}</ul> </div> <!-- 添加一个加载提示 --> <div id="loading-more" style="text-align: center; color: #999; display: none;"> <span>正在加载...</span> </div> <div id="no-more" style="text-align: center; color: #999; display: none;"> <span>没有更多了</span> </div> -
在
<body>标签结束前添加 JavaScript 代码:<script> (function($) { // 定义变量 var page = 1; // 当前页码 var tid = "{dede:field.tid/}"; // 获取当前栏目ID var isLoading = false; // 是否正在加载,防止重复请求 var hasMore = true; // 是否还有更多数据 // 加载更多数据的函数 function loadMore() { if (!hasMore || isLoading) { return; } isLoading = true; $('#loading-more').show(); // 使用 AJAX 请求下一页数据 $.ajax({ url: "/plus/ajax_list.php", // 我们将要创建的AJAX处理文件 type: "GET", data: { tid: tid, page: page }, dataType: "html", success: function(response) { // 如果返回的数据为空,说明没有更多内容了 if (response.trim() === '') { hasMore = false; $('#no-more').show(); } else { // 将新数据追加到列表末尾 $('#article-list').append(response); page++; // 页码自增 } }, error: function() { alert('加载失败,请稍后重试!'); }, complete: function() { isLoading = false; $('#loading-more').hide(); } }); } // 监听滚动事件 $(window).scroll(function() { // 当滚动到距离底部 100px 时,触发加载 if ($(document).height() - $(window).height() - $(window).scrollTop() < 100) { loadMore(); } }); })(jQuery); </script> </body>
第二步:创建 AJAX 数据处理文件 (ajax_list.php)
这是后端的核心,负责根据请求返回对应页码的数据。
-
创建文件: 在你的 DedeCMS 根目录下的
plus文件夹中,新建一个文件,命名为ajax_list.php。 -
编写 PHP 代码: 将以下代码复制到
ajax_list.php文件中。<?php /** * DedeCMS 下拉加载更多 AJAX 处理文件 */ // 引入数据库配置文件 require_once(dirname(__FILE__) . "/../include/config_base.php"); // 获取前端传递过来的参数 $tid = isset($tid) && is_numeric($tid) ? intval($tid) : 0; $page = isset($page) && is_numeric($page) ? intval($page) : 1; if ($tid == 0) { exit; // 如果没有栏目ID,则直接退出 } // 设置每页显示条数,这个值应该和模板中 {dede:list} 的 pagesize 一致 $pagesize = 10; // 获取当前栏目的信息 $typeinfo = $dsql->GetOne("SELECT * FROM `#@__arctype` WHERE id = $tid"); if (!$typeinfo) { exit; } // 设置分页参数 $pagenow = $page; $totalresult = -1; // -1 表示获取总数 $channelid = $typeinfo['channel']; // 获取栏目对应的模型ID // 调用 GetPageList 函数获取分页数据 // 这个函数会自动处理 limit,我们只需要传入当前页和每页条数 // 注意:这里我们手动构建查询,因为 GetPageList 本身是为分页条服务的 $addtable = $channelid > 0 ? $dsql->GetOne("SELECT addtable FROM `#@__channeltype` WHERE id = $channelid") : ''; $addtable = $addtable['addtable']; // 获取总记录数 $totalcount = $dsql->GetOne("SELECT COUNT(*) AS dd FROM `#@__archives` WHERE typeid='$tid' AND arcrank > -1"); $totalcount = $totalcount['dd']; // 计算总页数 $totalpage = ceil($totalcount / $pagesize); // 如果请求的页码超过了总页数,则返回空 if ($pagenow > $totalpage) { exit; } // 计算当前页的起始位置 $start = ($pagenow - 1) * $pagesize; // 查询当前页的数据 // 这里我们使用和列表页相同的查询逻辑,确保数据一致 $sql = "SELECT arc.*,tp.typedir,tp.typename,tp.corank,tp.isdefault,tp.defaultname,tp.namerule, tp.namerule2,tp.ispart,tp.moresite,tp.siteurl,tp.sitepath FROM `#@__archives` arc LEFT JOIN `#@__arctype` tp ON arc.typeid=tp.id WHERE arc.typeid='$tid' AND arc.arcrank > -1 ORDER BY arc.sortrank DESC, arc.id DESC LIMIT $start, $pagesize"; $dsql->SetQuery($sql); $dsql->Execute('al'); // 循环输出数据,生成HTML片段 $artlist = ''; while ($row = $dsql->GetArray('al')) { // 处理日期 $pubdate = MyDate('Y-m-d', $row['pubdate']); // 处理链接 (这里使用默认的URL规则) $arcurl = GetFileUrl($row['id'], $row['typeid'], $row['senddate'], $row['title'], $row['ismake'], $row['arcrank'], $row['namerule'], $row['typedir'], $row['money'], $row['filename'], $row['moresite'], $row['siteurl'], $row['sitepath']); // 拼接HTML,这里要和模板中的列表项结构保持一致 $artlist .= "<li>"; $artlist .= "<a href='{$arcurl}'>{$row['title']}</a>"; $artlist .= "<span>{$pubdate}</span>"; $artlist .= "</li>"; } // 输出HTML片段 echo $artlist; ?>
第三步:清理缓存并测试
-
清理 DedeCMS 缓存: 登录你的 DedeCMS 后台,进入【系统】->【SQL命令行工具】->【一键更新网站缓存】,点击“更新系统缓存”。 有时也需要更新一下栏目的HTML缓存。
-
测试: 访问你的列表页(如
/plus/list.php?tid=1),尝试向下滚动页面,应该就能看到新的内容被自动加载出来了。
常见问题与优化
-
数据不一致:
- 原因:
ajax_list.php中的查询逻辑和list_article.htm中的{dede:list}标签生成的 SQL 语句不一致。 - 解决:确保两者查询的字段、排序方式、
WHERE条件都完全一样,最稳妥的方法是复制list.php中生成列表的核心 SQL 语句到ajax_list.php中。
- 原因:
-
加载失败或返回404:
- 原因:
ajax_list.php文件路径错误,或者文件不存在。 - 解决:检查 JS 中的
url路径是否正确,确保文件已成功上传到/plus/目录。
- 原因:
-
SEO 考虑:
- 下拉加载是典型的 AJAX 实现,搜索引擎蜘蛛可能无法抓取到通过 JS 动态加载的内容。
- 解决方案:对于 SEO 要求极高的网站,建议保留原有的、完整的分页条 (
<div class="dede_pages">...</div>),这样,搜索引擎可以通过分页条抓取到所有页面,下拉加载可以作为一种提升用户体验的补充方案。
-
性能优化:
- 如果数据量很大,可以考虑在
ajax_list.php中只查询必要的字段(如id,typeid,title,pubdate,senddate等),而不是SELECT *,以减少数据库查询的数据量。
- 如果数据量很大,可以考虑在
这个教程已经覆盖了从零到一实现下拉加载的全部关键步骤,你可以根据自己的模板结构和需求进行微调,祝你成功!
