方案: 我有一个消息页面,其中包含一个容器,其左侧部分包含要发送消息的联系人和组,右侧有一个会话流。会话流通过ajax加载,而另一方面点击任何联系人或组。this is what it looks like将使用javascript文件加载右侧的内容,该文件包含每隔5秒执行一次的setinterval函数来检查数据库新消息和抓取消息,以便在会话div中显示它。
问题: 在第一次加载页面时,当我单击一个联系人或组时,显然内容已加载并且setinterval函数立即运行。当我单击另一个联系人或组时,再次加载内容并再次执行setinterval函数,问题是当您尝试查看chrome开发人员工具时,现在有两个setinterval函数正在运行。 As you can see in this image, there are two requests now, 1 for contact and 1 for group since i clicked a contact and a group。点击更多联系人和群组后,请求会不断增加。
这是在点击联系人或群组时通过ajax加载内容的代码:
$('.my_contacts a.list-group-item,.my_groups a.list-group-item,.new_message .list-group-item a').click(function(){
var href=$(this).attr('href');
$('.list-group-item').removeClass('active');
$(this).addClass('active');
$.ajax({
url:href,type:'post'
}).done(function(d){
$('#center-wing').html(d);
});
return false;
});
这是加载的ajax数据中的内容:
...more html content here
<script>
$(function(){
$.getScript("res/js/custom/in-page/message.js");
});
</script>
这是在message.js中每5秒运行一次的代码:
if(notification == true){
checkNewMsgId=setInterval(function(){
$.ajax({
url:'message/check_new_message/' + recipient + '/' + type,
type:'post'
}).done(function(d){
if(d.length > 0){
var obj={};
lastmsg.addClass('hide');
reset_inactivity();
for(var o in d){
var date=new Date(d[o].SentDate),time=format_time(date);
bubble_tpl_left.find('.bubble').attr('data-pk',d[o].Remarks);
if(d[o].SenderId == recipient){
lastmessagedate=format_date(date);
lastmessagetime=time;
}
if(type == 'CustomGroup') bubble_tpl_left.find('.msg_sender').removeClass('hide').html(d[o].FirstName + " " + d[o].LastName);
send(d[o].Reply,time,bubble_tpl_left);
obj.title=name;
obj.body=d[o].Reply;
}
if(pagehidden == true){
ding.play();push_notify(obj);
}else blop.play();
}
});
},5000);
}
...对不起长篇大论的家伙们。我真的坚持这一点,我已经尝试在执行setinterval之前清除间隔。
帮助将非常感谢大家:)
答案 0 :(得分:1)
(1)有两个功能。一个为群组加载对话的人(chart.xAxis
.tickFormat(function(d) {
return d3.time.format('%m %y')(new Date(d))
});
),另一个用于更新对话的消息(loadConversion()
)。
(2)当用户点击某个组时,请致电updateMessages()
。当该ajax调用返回时,它应该在等待5秒后调用loadConversion()
(而不是setTimeout()
)来执行setInterval()
。当updateMessages()
中的ajax呼叫返回时,它将在等待5秒后再次呼叫updateMessages()
以呼叫setTimeout()
。这会设置持续更新。
(3)但是当用户点击某个组时,您需要取消任何现有的计时器并在调用updateMessages()
之前中止任何未完成的ajax调用。 (或者你可以在进行下一个ajax调用之前在loadConversion()
内执行此操作。)
loadConversion()
函数返回timerId。将其存储在变量中。然后,您可以将其传递给setTimeout()
以取消计时器。
同样,clearTimout()
函数返回一个jqXHR对象,可用于中止ajax调用。
答案 1 :(得分:0)
将整个页面视为一个页面,将每个单独的区域视为页面的一部分 - 而不是新文档。
请勿在您为右侧部分加载的页面中加载您的javascript。 javascript应该是主文档的一部分,而不是该部分的一部分。您将获得多个时间间隔,因为每次重新加载页面的这一部分时,您都在运行该js并启动一个新的setInterval - 它继续运行。
使用隐藏的输入字段存储当前所选联系人的href
,并让您重复的AJAX代码块将该href发送到请求/从数据库返回新消息的PHP文件。
/* javascript/jQuery: */
$('.my_contacts a.list-group-item,.my_groups a.list-group-item,.new_message .list-group-item a').click(function(){
var href=$(this).attr('href');
$('#curr_href').val(href); //store current href
$('.list-group-item').removeClass('active');
$(this).addClass('active');
$.ajax({
type: 'post',
url: href
}).done(function(d){
$('#center-wing').html(d);
});
return false;
});
&#13;
<!-- HTML: -->
<!-- stick it down at bottom of body, like so -->
<input type="hidden" id="curr_href" />
</body>
</html>
&#13;
您重复的AJAX - 应该是主文档的一部分,而不是加载聊天历史记录 - 可以执行以下操作:
var href = $('#curr_href').val();
$.ajax({
type:'post',
url: href
}).done(function(d){
//etc etc etc
&#13;
在这个用例中,您还应该仔细查看使用递归setTimeout而不是setInterval:
http://www.erichynds.com/blog/a-recursive-settimeout-pattern