如何解决jQuery实时消息重复追加问题?
解决实时消息重复追加的问题
嘿,我太懂你现在的困扰了——每隔1秒就把所有历史消息重新往页面上塞一遍,肯定堆得乱七八糟!别慌,核心思路就是只请求和追加最新的未显示过的消息,咱们一步步来改:
关键逻辑梳理
我们需要记录已经显示过的最后一条消息的comment_id,每次请求后端时只索要比这个ID大的新消息,同时后端也要配合做相应的数据筛选。
具体修改步骤
1. 新增变量记录已处理的最新消息ID
在你的代码外层(比如全局作用域或者包裹代码的函数里)定义一个变量,用来存已经显示过的最大comment_id:
// 初始值设为0,确保第一次请求能拿到所有历史消息 let lastCommentId = 0;
2. 调整后端接口逻辑
让你的ClientCont/List_Files/fetchmessage接口新增接收last_id参数,查询数据库时只返回comment_id > last_id的消息。举个PHP端的示例(根据你实际的数据库操作调整):
$lastId = $this->input->post('last_id'); // 假设消息表为message_table,按文件夹ID和最新消息ID筛选 $newMessages = $this->db->where('folderid', $folderid) ->where('comment_id >', $lastId) ->order_by('date_entry', 'ASC') ->get('message_table') ->result_array(); echo json_encode($newMessages);
3. 前端请求与渲染逻辑更新
修改你的jQuery代码,把lastCommentId传给后端,只处理新消息并更新记录的ID:
window.setInterval(function(){ $.post('<?php echo base_url(); ?>ClientCont/List_Files/fetchmessage', { id: folderid, last_id: lastCommentId // 新增:传递已处理的最新消息ID }, function(data){ console.log(data); if(data.length > 0){ // 遍历每条新消息 data.forEach(function(item){ // 更新记录的最新消息ID if(item.comment_id > lastCommentId){ lastCommentId = item.comment_id; } // 重要:把原来的id改成class!重复id是不合法的HTML哦 let messageHtml = ` <div class="dateconvo" style="margin-top:20px;text-align:center;color:#D3D3D3">${item.date_entry}</div><br> <input class="oldid" type="hidden" value="${item.comment_id}"> <div class="usernamemessage" style="color:#D3D3D3">${atob(item.name_user)}</div> <div class="messageme" style="margin-left:10px;margin-top:10px;border-radius: .4em;background-color: #4CAF50!important; border-radius: 5px;box-shadow: 0 0 6px #B2B2B2; display: inline-block;padding: 10px 18px;position: relative;vertical-align: top;color:#FFFFFF">${item.message}</div> `; $('#previouscomment').append(messageHtml); }); // 滚动到消息底部(用scrollHeight更准确,不用写死数值) $("#previouscomment").animate({ scrollTop: $("#previouscomment")[0].scrollHeight }, "fast"); } // 移除原else里的"NO COMMENT"逻辑!不然每隔1秒没新消息就会重复添加提示 // 如果需要初始无消息的提示,建议在页面加载完成后单独判断处理 }, 'json' ); }, 1000);
额外优化小建议
- 把内联样式抽成CSS类,代码会更整洁,后期修改样式也更方便;
- 可以把
setInterval改成setTimeout,在请求成功后再触发下一次请求,避免网络延迟导致的请求堆积; - 给每个消息元素加个
data-comment-id="${item.comment_id}"属性,极端情况下能再次校验是否重复渲染。
内容的提问来源于stack exchange,提问作者Niño Cuenco
相关产品推荐
相关产品推荐

