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

Функция "Пользователь вводит" в чате

Я пытаюсь добавить в чат функцию "пользователь набирает"; чат, написанный на PHP + MySQL/Ajax.

Как это должно работать:

- Когда мой чат-партнер X начинает печатать, я вижу в своем окне: "X набирает текст"

- Когда я (названный Y) печатаю, он видит в своем окне чата: "Y печатает" (точно так же, как Yahoo Messenger).

Код, который я пробовал до сих пор:

<script type="text/javascript" language="javascript">
    var timer = 0;

    function reduceTimer() {
        timer = timer - 1;
        isTyping(true);
    }

    function isTyping(val) {
        if (val == 'true') {
            document.getElementById('typing_on').innerHTML = "User is typing...";
        } else {

            if (timer <= 0) {
                document.getElementById('typing_on').innerHTML = "No one is typing -blank space.";
            } else {
                setTimeout("reduceTimer();", 500);
            }
        }
    }
</script>

<label>
    <textarea onkeypress="isTyping('true'); timer=5;" onkeyup="isTyping('false')" name="textarea" id="textarea" cols="45" rows="5"></textarea>
</label>
<div id="typing_on">No one is typing -blank speace.</div>

Вопросы:

  • Если я остановлюсь на несколько секунд, чтобы подумать о моем написании, похоже, что я прекратил печатать. Существует ли более улокальный и менее сложный способ установки этой функции? Существует ли код для:

    • текстовое поле не пусто (пользователь нажал любую клавишу, так что начал печатать) → Сообщение: пользователь печатает.
    • пустое текстовое поле → Сообщение: пользователь не печатает.
    • текстовое поле не пустое, но пользователь не нажал ни одной клавиши дольше 5 секунд → Сообщение: пользователь не печатает.
  • Он показывает себе, что я печатаю; как я мог реализовать его или где, чтобы увидеть в моем окне чата "X пользователь печатает", а не "Я сам печатаю". То же самое для другого пользователя, он должен получить сообщение о том, что я набираю/не печатаю, а не о себе.

Спасибо.

4b9b3361

Ответ 1

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

var textarea = $('#textarea');
var typingStatus = $('#typing_on');
var lastTypedTime = new Date(0); // it 01/01/1970, actually some time in the past
var typingDelayMillis = 5000; // how long user can "think about his spelling" before we show "No one is typing -blank space." message

function refreshTypingStatus() {
    if (!textarea.is(':focus') || textarea.val() == '' || new Date().getTime() - lastTypedTime.getTime() > typingDelayMillis) {
        typingStatus.html('No one is typing -blank space.');
    } else {
        typingStatus.html('User is typing...');
    }
}
function updateLastTypedTime() {
    lastTypedTime = new Date();
}

setInterval(refreshTypingStatus, 100);
textarea.keypress(updateLastTypedTime);
textarea.blur(refreshTypingStatus);

Ответ 2

     <script>
        function isTyping() {
                document.getElementById('typing_on').innerHTML = "User is typing...! "; }

        function  notTyping (){
       document.getElementById('typing_on').innerHTML = "No one is typing ! "; }
    </script>

    <label>
        <textarea onkeypress="setTimeout(isTyping(),4000); setInterval(notTyping,5000)"  name="textarea" id="textarea" cols="45" rows="5"></textarea>
    </label>
    <div id="typing_on">No one is typing -blank speace.</div> 



    <!DOCTYPE html>
    <html>
       <head>
       </head>
       <body>

      <script>
        function isTyping() {
                document.getElementById('typing_on').innerHTML = "User is typing...! "; }
            
        function  notTyping (){
       document.getElementById('typing_on').innerHTML = "No one is typing ! "; }
    </script>

    <label>
        <textarea onkeypress="setTimeout(isTyping(),4000); setInterval(notTyping,5000)"  name="textarea" id="textarea" cols="45" rows="5"></textarea>
    </label>
    <div id="typing_on">No one is typing -blank speace.</div> 
       </body>
    </html>

Ответ 3

Вы можете использовать JQuery для обработки события keypress вместо HTML. Вы можете попробовать что-то вроде этого. Затем установите значение #typing по умолчанию на div, поскольку пользователь не печатает.

//EXECUTES WHEN KEY IS PRESSED IN SPECIFIED ELEMENT
$("#textarea").keypress(function(){
numMiliseconds = 500;

//THIS IF STATEMENT EXECUTES IF USER CTRL-A DELETES THE TEXT BOX
if ($("textarea") == ""){
    $("#typing_on").text("User has cleared the text box");
}

$("#typing_on").text("User is typing").delay(numMiliseconds).queue(function(){
    $("#typing_on").text("User has stopped typing");
    }
});

Ответ 4

Theres отличный библиотечный плагин под названием underscore.js

Среди многих полезных функций можно назвать _. debounce, который можно использовать для отслеживания ввода:

var typing, typingStarted, typingStopped;

typing = false;

typingStopped = _.debounce((function() {
  if (!typing) {
    return;
  }
  typing = false;
  console.log('typing is done so do what ever you need to do to notify it');
}), 5000);

typingStarted = function() {
  if (this.typing) {
    return;
  }
  typing = true;
  console.log('typing has started so do what ever you need to do to notify it');
};

document.querySelector("textarea").oninput = function(event) {
  typingStarted();
  typingStopped();
  return
};

Как это работает, так это то, что при вводе текстовой области вызывается typpingStarted и устанавливает типизацию на true, чтобы она не вызывалась снова. Затем вызывается typingStopped, но вызывается только функция, завернутая в _.debounce после 5000 мс, которая указана как второй аргумент _.debounce. Однако, если вы снова вызовите typingStopped, он вернет обратный отсчет reset до 5000 мс от того места, где он был. Так как typingStopped вызывается для каждого входа, он будет выполнять только типизацию = false через 5 секунд между нажатиями клавиш.