Сообщение пользователя Ajax для чата

Я пытаюсь создать систему ввода текста в стиле facebook. Но у меня есть один вопрос о keypress.

Итак, мой код работает нормально, но я хочу изменить что-то еще, например keypress, keyup, paste ect.

Я использую следующие коды javascript и ajax. В следующем моем коде ajax работает как if ($.trim(updateval).length == 0) { send width notyping.php notyping.php posting 0, а 0 не отображает вводное сообщение.

Если if ($.trim(updateval).length > 13) { send with usertyping.php usertyping.php posting 1 и 1 отображается сообщение для ввода текста.

Проблема здесь, если пользователь остановлен, чтобы набрать какое-то сообщение, а затем каждый раз говорит о наборе текста. Что мне делать, чтобы исправить это, кто-нибудь может мне помочь в этом отношении?

Все коды ajax и javascript находятся здесь:

;
(function($) {
  $.fn.extend({
    donetyping: function(callback, timeout) {
      timeout = timeout || 1000; // 1 second default timeout
      var timeoutReference,
        doneTyping = function(el) {
          if (!timeoutReference) return;
          timeoutReference = null;
          callback.call(el);
        };
      return this.each(function(i, el) {
        var $el = $(el);
        // Chrome Fix (Use keyup over keypress to detect backspace)
        // thank you @palerdot
        $el.is(':input') && $el.is(':input') && $el.on('keyup keypress paste', function(e) {
          // This catches the backspace button in chrome, but also prevents
          // the event from triggering too premptively. Without this line,
          // using tab/shift+tab will make the focused element fire the callback.
          if (e.type == 'keypress' && e.keyCode != 8) return;

          // Check if timeout has been set. If it has, "reset" the clock and
          // start over again.
          if (timeoutReference) clearTimeout(timeoutReference);
          timeoutReference = setTimeout(function() {
            // if we made it here, our timeout has elapsed. Fire the
            // callback
            doneTyping(el);
          }, timeout);
        }).on('blur', function() {
          // If we can, fire the event since we're leaving the field
          doneTyping(el);
        });
      });
    }
  });
})(jQuery);

Проверка текстового значения, если оно равно 0, тогда отправить данные 0 для пользователя без ввода

$('#chattextarea').donetyping(function() {
  var typingval = $("#chattextarea").val();
  var tpy = $('#tpy').val();
  if ($.trim(typingval).length == 0) {
    $.ajax({
      type: "POST",
      url: "/notyping.php",
      data: {
        tpy: tpy
      },
      success: function(data) {

      }
    });
  } 

Проверка текстового значения > 13, а затем передача данных - 1 для ввода пользователем. (Возможно, нужно изменить этот оператор if)

if ($.trim(typingval).length > 13) {
    $.ajax({
      type: "POST",
      url: "/usertyping.php",
      data: {
        tpy: tpy
      },
      success: function(data) {

      }
    });
  }

});

Проверить и отобразить ввод пользователя:

function getTyping(){
     setInterval(function(){
         var tpy = $('#tpy').val();
           $.ajax({
            type: "POST",
            url: "/getTyping.php",
            data: { tpy: tpy },
            success: function(data) {
               $('#s').html(data);
              }
             });
         },1000);
    }   
getTyping();

HTML

<textarea id="chattextarea"></textarea>
<div id="s"></div>

Ответ 1

У меня есть некоторые замечания о вашем коде и приложении:

  • Во-первых, и как упоминалось @rory-mccrossan, если у вас нет инфраструктуры facebook, google или microsoft,..., я думаю, что это действительно плохая идея использовать Ajax вместо Websockets для приложения реального времени, такого как чат.

  • Теперь о вашем коде, я не знаю, что делают ваши скрипты PHP за сценой, но я думаю, что вам не нужно отправлять два запроса, чтобы указать, что пользователь печатает или нет, вы может ограничивать это одним запросом, который должен быть отправлен, когда пользователь вводит в противном случае, он, конечно, не печатает. Конечно, вы можете использовать какой-то тайм-аут в вашем getTyping.php script, чтобы ограничить срок службы "типизации" (например, 5 секунд), поэтому, если запрос отправляется после этого таймаута, вы можете знать, что ваш пользователь не печатает.

  • И о вашей текущей проблеме, я думаю, что, поскольку статус "не печатать" просто запускается, когда текстовая область пуста, поэтому, конечно, после прекращения записи и длины текущего текста больше 13, поэтому статус "не набрав" никогда не будет запущен (отправлен), поэтому вам нужен тайм-аут, как я сказал вам во 2-м пункте...

  • Кроме того, не забывайте проблему с кешем при получении статуса с помощью getTyping.php script, который не должен кэшироваться (или, по крайней мере, в течение очень ограниченного периода времени)...

  • Затем я не вижу в вашем опубликованном коде какую-либо информацию (ы), чтобы идентифицировать текущего пользователя и тот, который конвертирует с ним... возможно, вы не включили это в вопрос, я не знаю!

...

Надеюсь, что это поможет.

Ответ 2

Мое предложение здесь иметь внешний setInterval, который каждые 3 секунды сохраняет текущий текст в переменной oldValue и сравнивает currentText с oldValue, если они равны, тогда пользователь перестает писать, а затем посылает ajax на notyping.php

Ответ 3

обновленный код приведен ниже Я создал функцию getTyping, которая будет вызываться в каждый интервал времени в 1 секунду, если пользователь начнет печатать.

в get getTyping setinterval function я называется функцией check_which_function.

в функции check_which_funciton я использовал ваш код, применяя условия для длины значения textarea, которая находится в вложенном выражении if else, поэтому теперь

если пользователь начнет вводить текст, но если длина содержимого равна 0, чем

$. trim (typingval).length == 0 будет выполняться до тех пор, пока длина не будет равна 12

если длина содержимого больше 13, чем

$. trim (typingval).length > 13 выполнит

по умолчанию функция getTyping2() выполняется в этой функции getTyping.php ajax call идет

<script>
    (function ($) {
        $.fn.extend({
            donetyping: function (callback, timeout) {
                timeout = timeout || 1000; // 1 second default timeout
                var timeoutReference,
                        doneTyping = function (el) {
                            if (!timeoutReference)
                                return;
                            timeoutReference = null;
                            callback.call(el);
                        };
                return this.each(function (i, el) {
                    var $el = $(el);
                    // Chrome Fix (Use keyup over keypress to detect backspace)
                    // thank you @palerdot
                    $el.is(':input') && $el.is(':input') && $el.on('keyup keypress paste', function (e) {
                        // This catches the backspace button in chrome, but also prevents
                        // the event from triggering too premptively. Without this line,
                        // using tab/shift+tab will make the focused element fire the callback.
                        if (e.type == 'keypress' && e.keyCode != 8)
                            return;

                        // Check if timeout has been set. If it has, "reset" the clock and
                        // start over again.
                        if (timeoutReference)
                            clearTimeout(timeoutReference);
                        timeoutReference = setTimeout(function () {
                            // if we made it here, our timeout has elapsed. Fire the
                            // callback
                            doneTyping(el);
                        }, timeout);
                    }).on('blur', function () {
                        // If we can, fire the event since we're leaving the field
                        doneTyping(el);
                    });
                });
            }
        });
    })(jQuery);


    function getTyping2() {
        var tpy = $('#tpy').val();
        $.ajax({
            type: "POST",
            url: "/getTyping.php",
            data: {tpy: tpy},
            success: function (data) {
                $('#s').html(data);
            }
        });
    }
    function check_which_action() {
        $('#chattextarea').donetyping(function () {
        var typingval = $("#chattextarea").val();
        var tpy = $('#tpy').val();
        if ($.trim(typingval).length == 0) {
            $.ajax({
                type: "POST",
                url: "/notyping.php",
                data: {
                    tpy: tpy
                },
                success: function (data) {

                }
            });
        }

        else if ($.trim(typingval).length > 13) {
            $.ajax({
                type: "POST",
                url: "/usertyping.php",
                data: {
                    tpy: tpy
                },
                success: function (data) {

                }
            });
        }
        else {
            getTyping2() ;
        }

    });
    }
    function getTyping() {
        setInterval(check_which_action, 1000);
    }
    getTyping();

</script>

<textarea id="chattextarea"></textarea>
<div id="s"></div>