我写了一个小聊天插件,我需要在我的网站上使用。它使用HTML中的简单结构,如下所示:
<div id="div_chat">
<ul id="ul_chat">
</ul>
</div>
<div id="div_inputchatline">
<input type="text" id="input_chatline" name="input_chatline" value="">
<span id="span_sendchatline">Send</span>
</div>
点击了&#39;当然,该Span元素上的绑定事件。然后,当用户插入消息并点击&#34;发送&#34; span元素,有一个Javascript函数,调用Ajax事件将消息插入MySQL数据库:
function function_write_newchatline()
{
var chatline = $('#input_chatline').val();
$.ajax
({
type: "POST",
url: "ajax-chat-writenewline.php", //1: ok, 0: errore
data: ({'chat_line': chatline}),
dataType: "text",
cache: false,
success: function(ajax_result)
{
function_get_newchatlines();
}
});
}
并且,如果消息成功插入到DB中,它会调用一个函数来读取新行并将它们放在我之前发布的HTML结构中:
function function_get_newchatlines()
{
$.ajax
({
type: "POST",
url: "ajax-chat-loadnewlines.php", //1: ok, 0: errore
data: '',
dataType: "text",
cache: false,
success: function(ajax_result) //example of returned string: 'message1>+<message2>+<message3'
{
//explode new chat lines from returned string
var chat_rows = ajax_result.split('>+<');
for (id_row in chat_rows)
{
//insert row into html
$('#ul_chat').prepend('<li>' + chat_rows[id_row] + '</li>');
}
$('#span_sendchatline').html('Send');
}
});
}
注意:&#39; ajax_result&#39;仅包含html实体,而不包含特殊字符,因此即使消息包含&#39;&gt; +&lt;&#;;它也会被使用Ajax调用的php脚本编码,然后从此JS函数处理。
现在,出现了一个奇怪的行为:发布新消息时,Opera,Firefox甚至IE8都按预期运行良好,如下所示:
但是,当我打开Chrome窗口时,我看到了:
正如您所看到的,在Chrome中,消息会多次显示(每次增加的数量,每封邮件最多8行)。我检查了内部调试查看器,并没有看到&#34;读取新行&#34;函数被多次调用,所以它应该是与Jquery事件或其他东西相关的东西。
希望我的解释清楚,如果您还需要其他任何内容,请告诉我们。)
谢谢,Erenor。
修改
正如Shusl所指出的,我忘了提到函数function_get_newchatlines()
被setInterval(function_get_newchatlines, 2000)
定期调用到Javascript中。
EDIT2
这里是来自Ajax调用的PHP文件的代码条带,用于获取新的聊天行(我不会想到诸如&#34; session_start()&#34;或mysql连接之类的东西这里需要的东西)
//check if there's a value for "last_line", otherwise put current time (usually the first time a user logs into chat)
if (!isset($_SESSION['prove_chat']['time_last_line']) || !is_numeric($_SESSION['prove_chat']['time_last_line']) || ($_SESSION['prove_chat']['time_last_line'] <= 0))
{
$_SESSION['prove_chat']['time_last_line'] = microtime(true);
}
//get new chat lines
$result = mysql_query("select * from chat_module_lines where line_senttime > {$_SESSION['prove_chat']['time_last_line']} order by line_senttime asc; ", $conn['user']);
if(!$result || (mysql_num_rows($result) <= 0))
{
mysql_close($conn['user']); die('2-No new lines');
}
//php stuff to create the string
//....
die($string_with_chat_lines_to_be_used_into_Javascript);
无论如何,我认为,如果问题是这个PHP脚本,我也会在其他浏览器中遇到类似的错误:)
EDIT4
这里是将点击事件绑定到&#34;发送&#34;的代码。 span元素:
$('#span_sendchatline').on('click', function()
{
//check if there's already a message being sent
if ($('#span_sendchatline').html() == 'Send')
{
//change html content of the span element (will be changed back to "send"
//when the Ajax request completes)
$('#span_sendchatline').html('Wait..');
//write new line
function_write_newchatline();
}
//else do nothing
});
(感谢f_puras添加了缺失的标签:)
答案 0 :(得分:2)
我会做以下其中一项:
选项1:
在function_write_newchatline()中调用ajax之前停止计时器,并在ajax调用返回时启动计时器。
function function_write_newchatline()
{
var chatline = $('#input_chatline').val();
stop_the_timer();
$.ajax
({
type: "POST",
url: "ajax-chat-writenewline.php", //1: ok, 0: errore
data: ({'chat_line': chatline}),
dataType: "text",
cache: false,
success: function(ajax_result)
{
function_get_newchatlines();
},
complete: function() {
start_the_timer();
}
});
}
选项2:
在ajax调用的成功事件中根本不调用function_get_newchatlines()。只让计时器检索聊天条目。
function function_write_newchatline()
{
var chatline = $('#input_chatline').val();
$.ajax
({
type: "POST",
url: "ajax-chat-writenewline.php", //1: ok, 0: errore
data: ({'chat_line': chatline}),
dataType: "text",
cache: false,
success: function(ajax_result)
{
// do nothing
}
});
}
我认为在用户添加聊天条目之后调用的function_get_newchatlines()和定时器对function_get_newchatlines()的定期调用之间存在一些竞争条件。
选项3:
使用setTimeout而不是setInterval。当浏览器忙时,setInterval会搞乱。所以在setTimeout函数的最后再次调用setTimeout。