评论区改版:嵌套层级、ajax 提交和三个绕不开的坑
评论模板是主题里最容易被忽略的。多数人抄一份 comment.php,能用就不再看了。真改起来,坑不少。 先搞清数据层。 评论不是一次全取回来的。$article->Comments 只含一级(或已展开的部分),回复靠 $comment
评论模板是主题里最容易被忽略的。多数人抄一份 comment.php,能用就不再看了。真改起来,坑不少。
先搞清数据层。
评论不是一次全取回来的。$article->Comments 只含一级(或已展开的部分),回复靠 $comment->Comments 递归。
模板里通常是个双层 foreach。外层遍历主评论,内层遍历 $comment->Comments 拿回复。Z-Blog 默认支持到两层,再深的回复会平铺到第二层。
想要无限层级?得自己算。每个 Comment 有 ParentID,但直接拿 ParentID 构树很麻烦——数据是一次性按文章取的,没有索引。我的做法是在 PHP 层先跑一遍,建个 parent_id => [children] 的哈希表,模板里只负责递归渲染一个函数。
嵌套一深,缩进就难看。三层以后,左边距挤得没救了。所以实际建议是:超过两层做「@某人」的平铺,别做视觉嵌套。
ajax 提交这块。
原生表单提交会刷新整页,体验差。改成 ajax 要动的地方有三个。
第一,提交地址。不是当前页 URL,是后台的 cmd.php,带上 act=cmt。这点容易错,直接 post 到文章地址会返回整页 HTML。
第二,验证码。开了验证码的话,ajax 请求里必须带上,否则一律失败。而验证码图片刷新是个独立接口,错误时得手动触发刷一次,不然用户看到的是旧码,怎么输都不对。
第三,返回值判断。返回的 json 里 err 字段,err.code === 0 才算成功。有些主题只判断 HTTP 200,结果验证码错了也提示发布成功,评论其实没进库。
这个错我见过不止一次。用户以为发成功了,刷新一看没有,再发一遍,两遍都失败。
三个绕不开的坑。
坑一:新评论的 HTML 谁生成。ajax 返回的只是数据,DOM 得前端拼。拼的时候必须手动转义用户输入——后端入库时存的是原文,直接 innerHTML 就是个 XSS。评论内容可以用 textContent,或者后端一并返回转义后的版本。
坑二:评论数不更新。发完评论,导航上的评论计数还是旧的,因为那是模板编译时写死的。要么重新请求,要么前端自己 +1。
坑三:审核态。开了评论审核,ajax 成功返回但前台不显示,因为它 IsChecking 为真。得给个提示「已提交,审核后显示」,不然用户以为没发出去,反复提交。
你站上评论审核是开着的还是关的?开的话,第三坑一定要处理。