打印 上一主题 下一主题

Discuz帖子列表页新回复帖自动提示机制分析

跳转到指定楼层
楼主
SetYun 发表于 2018-10-20 10:46:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
基于版本:Discuz! X 2.0


x2 新添加了一个功能当用户查看一个版块帖子列表页,短时间内没有刷新操作,如果有其它用户在相同版块发帖时,一定时间后,查看该版未作刷新操作的用户的帖子列表页会一条有新回复主题的帖的提醒


具体实现我们可以了解一下如下:

当用户查看一个版块帖时,程序模板 ./template/default/forum/forumdisplay.htm
此文件在版块为非图片版模式 (empty($_G['forum']['picstyle']) ) 并且为按默认的最新回复排序看帖 ($_G['gp_orderby'] == 'lastpost')时,会在版块的帖子列表页底部加一段 js 代码
  • <script type="text/javascript">checkForumnew_handle = setTimeout(function () {checkForumnew($_G[fid], lasttime);}, checkForumtimeout);</script>


该 js 会使用 setTimeout 函数 根据 forum.js 里面设定的 checkForumtimeout 的值(程序默认为30000 即30秒)执行 checkForumnew() 函数,如下
  • function checkForumnew(fid, lasttime) {
  •         var timeout = checkForumtimeout;
  •         var x = new Ajax();
  •         x.get('forum.php?mod=ajax&action=forumchecknew&fid=' + fid + '&time=' + lasttime + '&inajax=yes', function(s){
  •                 if(s > 0) {
  •                         if($('separatorline')) {
  •                                 var table = $('separatorline').parentNode;
  •                         } else {
  •                                 var table = $('forum_' + fid);
  •                         }
  •                         if(!isUndefined(checkForumnew_handle)) {
  •                                 clearTimeout(checkForumnew_handle);
  •                         }
  •                         removetbodyrow(table, 'forumnewshow');
  •                         var colspan = table.getElementsByTagName('tbody')[0].rows[0].children.length;
  •                         var checknew = {'tid':'', 'thread':{'common':{'className':'', 'val':'<a href="javascript:void(0);">有新回复的主题,点击查看', 'colspan': colspan }}};
  •                         addtbodyrow(table, ['tbody'], ['forumnewshow'], 'separatorline', checknew);
  •                 } else {
  •                         if(checkForumcount < 50) {
  •                                 if(checkForumcount > 0) {
  •                                         var multiple =  Math.ceil(50 / checkForumcount);
  •                                         if(multiple < 5) {
  •                                                 timeout = checkForumtimeout * (5 - multiple + 1);
  •                                         }
  •                                 }
  •                                 checkForumnew_handle = setTimeout(function () {checkForumnew(fid, lasttime);}, timeout);
  •                         }
  •                 }
  •                 checkForumcount++;
  •         });
  • }


forum.js 中的 checkForumnew() 会 实例一个 Ajax对象
通过ajax 请求 forum.php?mod=ajax&action=forumchecknew&fid=' + fid + '&time=' + lasttime + '&inajax=yes

通过地址很容易看到请求的 ./source/module/forum/forum_ajax.php
该文件根据传过来版块fid的值 从 forum_forum 表查出该版块记录有最新回复的主题帖的 lastpost 的字段的值 ,并不是从 forum_post 表查的最新帖
然后判断 ajax 所请求的时间是否大于 此字段记录中所记录的最新帖子的时间 来返回是否存在最新帖
如果请求的时间小于最新帖时间 那表示有最新帖 则返回 1 否则返回 0

返回是否有新帖被传成 forum.js 中的 checkForumnew()  中 function(s) s值  
通过判断 s 值

如果 s 值为0 没有最新帖 forum.js 会根据一定算法把 慢慢延长 ajax 请求查询是否有新帖的周期 以防止过去频繁的查询

如果  s 值为1 有最新帖
forum.js 判断了checkForumnew_handle 来清除 setTimeout() 方法设置的 timeout 的值,以防止用户未点击查看新帖提示之前程序做重复的查询浪费资源,并且使用自定义函数 addtbodyrow 添加新帖提醒节点及获取新帖的ajax
onclick="ajaxget(\'forum.php?mod=ajax&action=forumchecknew&fid=' + fid+ '&time='+lasttime+'&uncheck=1&inajax=yes\', \'forumnew\');"


此时用户就会在帖子列表页看到上面图中所提示的现状 “有新回复的主题,点击查看”。

当用户点击 “有新回复的主题,点击查看”时, 程序会以ajax 请求 forum.php?mod=ajax&action=forumchecknew&fid=' + fid+ '&time='+lasttime+'&uncheck=1&inajax=yes  地址

同样 通过地址很容易看到请求 ./source/module/forum/forum_ajax.php 文件, 而地址多了一个 uncheck 参数,
根据uncheck进入查询具体新主题的判断,程序从 forum_thread 根据当前 ajax 请求的时间,查出最新的帖子返回,此时include template('forum/ajax_threadlist');


包含一个  ./template/default/forum/ajax_threadlist.htm 模板文件 将最新回复的帖子标题等内容 输出展示在帖子列表
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|SetYun ( 辽ICP备16005250号

GMT+8, 2024-4-20 22:29 , Processed in 0.040224 second(s), 4 queries , File On.

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表