Подтвердить что ты не робот

Проблема 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>

Там '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();
    }
  });
}

И, если сообщение успешно вставлено в БД, оно вызывает функцию для чтения новых строк и помещает их в структуру 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');
    }
  });
}

Примечание: "ajax_result" содержит только html-объекты, а не специальные символы, поэтому даже если сообщение содержит " > + <", оно кодируется php script, вызванным с помощью Ajax, перед обработкой из этой функции JS.

Теперь возникает странное поведение: при публикации новых сообщений Opera, Firefox и даже IE8 работают хорошо, как и предполагалось, например:

A screen taken from Firefox

Но когда я открываю окно Chrome, я вижу следующее:

A screen taken from Chrome

Как вы можете видеть, в Chrome сообщения отображаются несколько раз (каждый раз увеличивая число, до 8 строк на сообщение). Я проверил внутренний просмотрщик отладки, и не кажется, что функция "читать новые строки" вызывается более одного раза, поэтому она должна быть связана с событиями JQuery или чем-то еще.

Надеюсь, что я объяснил свое объяснение, если вам нужно что-нибудь еще, дайте мне знать:)

Спасибо, Эренор.

ИЗМЕНИТЬ

Как отметил Шуслов, я забыл упомянуть, что функция function_get_newchatlines() периодически вызывается a setInterval(function_get_newchatlines, 2000) в Javascript.

EDIT2

Вот фрагмент кода из файла PHP, который называется Ajax, чтобы получить новые строки чата (я не думаю, что здесь нужны такие вещи, как "session_start()" или "соединение mysql" )

//check if there 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 script, я тоже получал бы подобные ошибки в других браузерах:)

EDIT4

Здесь код, который связывает событие click с элементом диапазона "Отправить":

$('#span_sendchatline').on('click', function()
{
  //check if there 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 для добавления отсутствующего тега:)

4b9b3361

Ответ 1

Я бы сделал одно из следующих действий:

вариант 1:

остановите таймер непосредственно перед вызовом ajax в функции function_write_newchatline() и запустите таймер при возврате вызова 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:

Не вызывать функцию function_get_newchatlines() вообще в событии успеха вызова ajax. Пусть только таймер получает записи в чате.

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(), которое вызывается после добавления пользователем чата и периодического вызова функции_get_newchatlines() таймером.

вариант 3:

Используйте setTimeout вместо setInterval. setInterval может испортить работу, когда браузер занят. Поэтому в конце функции setTimeout снова вызовите setTimeout.