我正在建立一个对话系统,让2个人可以互相聊天。我已经制作了一个AJAX函数,它每2秒更新一次包含消息的DIV框。
这是按预期工作,在用户撰写邮件之后。为什么不立即运行AJAX调用?
// SET AUTORUN updateMessages() EVERY 2 SECONDS
$(document).ready(function() {
var interval
window.onload = function(){
interval = setInterval('updateMessages()', 2000);
};
});
// UPDATE #mail_container_conversation
function updateMessages() {
$.ajax({
type: "POST",
url: "<?php echo site_url(); ?>mail/ajaxupdate/<?php echo $user; ?>",
data: dataString,
success: function(data){
$("#mail_container_conversation").html(data);
}
});
}
// SEND NEW MESSAGE
$(function(){
$("#mail_send").submit(function(){
dataString = $("#mail_send").serialize();
$.ajax({
type: "POST",
url: "<?php echo site_url(); ?>mail/send",
data: dataString,
success: function(data){
updateMessages();
$(".mail_conversation_answer_input").val('');
}
});
return false;
});
});
答案 0 :(得分:2)
如果其余代码有效,问题可能就是这段代码:
$(document).ready(function() {
var interval
window.onload = function(){
interval = setInterval('updateMessages()', 2000);
};
});
window.onload
,因为您已将其包装在DOM-ready回调中。 setInterval
请改为尝试:
$(function () {
setInterval(updateMessages, 2000);
});
进一步改进 - 使用AJAX避免间隔:
在处理AJAX时,您应该避免使用间隔,因为如果服务器响应时间超过两秒钟,您最终可能会堆叠到服务器的呼叫。 setInterval
无需关心您的服务器是否有时间做出响应,无论如何都会每2秒调用一次。
我建议您使用超时,并在Ajax调用的完整回调中启动新的超时。
在您的情况下,它可能看起来像这样:
$(function () {
// Make the first call immediately when the DOM is ready
updateMessage();
});
function updateMessages() {
$.ajax({
type: "POST",
url: "<?php echo site_url(); ?>mail/ajaxupdate/<?php echo $user; ?>",
data: dataString,
success: function(data){
$("#mail_container_conversation").html(data);
// Make a new call, 2 seconds after you've
// received a successful respose
setTimeout(updateMessages, 2000);
}
});
}
答案 1 :(得分:2)
您应该为setTimeout
/ setInterval
函数提供函数而不是字符串。而且您也无需在窗口加载事件上设置间隔。您可以将它作为DOM准备的一部分保留:
$(function() {
updateMessages(); // don't wait 2 seconds for first update
setInterval(updateMessages, 2000); // update every 2 seconds
});
其他所有内容似乎应该按预期工作,只要在没有收到数据时您的后退工作(参考dataString
)。
我希望您确实意识到您正在使用隐含的全局变量并理解为什么这可能是一个大问题(再次参考dataString
)。
我会将整个代码重写为以下内容,删除隐含的全局变量dataString
,不会使用其他函数污染全局范围,并使用setTimeout
而不是间隔,这在某些情况下可能会有问题(虽然在你的情况下,因为它'每2秒运行一次,如果没有额外的非常复杂的客户端脚本执行,它应该不是问题)
我将所有内容保存在函数闭包的本地范围内:
$(function() {
var timeout = null;
var form = $("#mail_send").submit(function(evt){
evt.preventDefault();
$(".mail_conversation_answer_input", form).val("");
updateMessages();
});
var updateMessages = function() {
// we don'w want submit to interfere with auto-updates
clearTimeout(timeout);
$.ajax({
type: "POST",
url: "<?php echo site_url(); ?>mail/send",
data: form.serialize(),
success: function(data){
$("#mail_container_conversation").html(data);
timeout = setTimeout(updateMessages, 2000);
}
});
};
// start updating
updateMessages();
});
此代码要求您的服务器端(在/mail/send
上处理)了解当没有发布任何内容(没有数据)时,它不会在会话中添加空行,而是知道这只是一个更新呼叫。此功能现在只使用一个服务器端URL而不是其中两个。如果您仍然需要两个,那么这段代码应该可以解决问题:
$(function() {
var timeout = null;
var url = {
update: "<?php echo site_url();?>mail/ajaxupdate/<?php echo $user;?>",
submit: "<?php echo site_url();?>mail/send",
use: "update"
};
var form = $("#mail_send").submit(function(evt){
evt.preventDefault();
url.use = "submit";
$(".mail_conversation_answer_input", form).val("");
updateMessages();
});
var updateMessages = function() {
// we don'w want submit to interfere with auto-updates
clearTimeout(timeout);
$.ajax({
type: "POST",
url: url[url.use],
data: form.serialize(),
success: function(data){
$("#mail_container_conversation").html(data);
url.use = "update";
timeout = setTimeout(updateMessages, 2000);
}
});
};
// start updating
updateMessages();
});
答案 2 :(得分:1)
问题是updateMessages()
尝试将datastring
发送到服务器,但在.submit()
函数运行之前,这不会被填写。
我不知道你应该把它放在那里,因为我不知道mail/ajaxupdate
脚本的期望。如果在没有任何反应时调用它,我怀疑根本不需要表单数据,所以你可以给一个空字符串。
如果您检查了Javascript控制台,我会打赌您会看到有关尝试序列化undefined
的错误消息。
答案 3 :(得分:0)
尝试
$(document).ready(function() {
setInterval('updateMessages()', 2000);
});
答案 4 :(得分:0)
您的文档就绪电话中不需要window.onload
。
$(document).ready(function() {
setInterval('updateMessages()', 2000);
});
这应该足以让它开始。
就像现在一样,一旦DOM准备就绪,你就会要求它等待窗口加载..但到那时它已经加载了,所以没有任何反应。