Chrome问题 - 聊天行多次返回

Ere*_*Paz 10 html javascript jquery google-chrome

我写了一个小聊天插件,我需要在我的网站上使用.它使用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>
Run Code Online (Sandbox Code Playgroud)

当然,在Span元素上有一个'click'绑定事件.然后,当用户插入消息并单击"发送"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();
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

并且,如果消息成功插入到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');
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

注意:'ajax_result'只包含html实体,而不包含特殊字符,所以即使消息包含'> + <',它也会被用Ajax调用的php脚本编码,然后从这个JS函数处理.

现在,出现了一个奇怪的行为:发布新消息时,Opera,Firefox甚至IE8都按预期运行良好,如下所示:

从Firefox获取的屏幕

但是,当我打开Chrome窗口时,我看到了:

从Chrome获取的屏幕

如您所见,在Chrome中,邮件会多次显示(每次增加的数量,每封邮件最多8行).我检查了内部调试查看器,似乎没有多次调用"读取新行"函数,因此它应该是与Jquery事件或其他相关的东西.

希望我的解释清楚,如果您还需要其他任何东西,请告诉我:)

谢谢,Erenor.

编辑

正如Shusl指出的那样,我忘了提到函数function_get_newchatlines()是通过setInterval(function_get_newchatlines, 2000)Javascript 定期调用的.

EDIT2

这是一个由Ajax调用的PHP文件中的代码条带来获取新的聊天行(我不认为这里需要"session_start()"或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);
Run Code Online (Sandbox Code Playgroud)

无论如何,我认为,如果问题是这个PHP脚本,我会在其他浏览器中得到类似的错误:)

EDIT4

这是将click事件绑定到"Send"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
});
Run Code Online (Sandbox Code Playgroud)

(感谢f_puras添加缺少的标签:)

Yon*_*ciu 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();
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

选项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
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

我认为在用户添加聊天条目后调用的 function_get_newchatlines() 与计时器定期调用 function_get_newchatlines() 之间存在一些竞争条件。

选项3:

使用 setTimeout 而不是 setInterval。当浏览器繁忙时,setInterval 可能会把事情搞砸。所以在setTimeout函数结束时再次调用setTimeout。