聊天中的“用户正在输入”功能

19

我正在尝试在使用PHP + MySQL/Ajax编写的聊天中添加“用户正在输入”功能。

它应该如何工作:

- 当我的聊天伙伴X开始输入时,我会在我的聊天框中看到:“X正在输入”

- 当我(名为Y)正在输入时,他会在他的聊天框中看到:“Y正在输入”(就像雅虎通一样)。

我尝试过的代码:

<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>

问题:

  1. 如果我停顿几秒钟来思考我的拼写,它看起来就像我停止了打字。有没有更相关且不那么复杂的方法来设置此功能?是否有可能用以下代码:

    • 文本框不为空(用户按下任意键开始输入)-> 消息:用户正在输入。
    • 文本框为空 -> 消息:用户未输入。
    • 文本框不为空,但用户已经超过5秒钟没有按键 -> 消息:用户未在输入。
  2. 它对自己显示我正在输入;如何实现或在哪里实现以便在聊天框中看到“X用户正在输入”,而不是“我正在输入”。同样对于其他用户,他应该收到关于我正在/未正在输入的消息,而不是关于他自己。

谢谢。


+1 给你。你解决了吗?因为我也需要完全和你一样的东西。 - Human Being
某人在哪里放置发送数据的Ajax代码? - Omari Victor Omosa
5个回答

14

我创建了一个代码片段,可能对你有帮助。思路是使用 JavaScript 的 setInterval 函数来刷新活动消息。

var textarea = $('#textarea');
var typingStatus = $('#typing_on');
var lastTypedTime = new Date(0); // it's 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);

1
某人在哪里放置用于发送数据的ajax代码? - Omari Victor Omosa
这很完美...但我想问一下,你知道数据库循环的方式吗?如果我正在输入,我该如何让用户将其输入传递给另一个用户? - james Oduro
2
@jamesOduro,通过套接字发送打字数据可能比插入数据库更好的想法。 - marukobotto

3

var isTyping = false;
var isNotTyping;
  document.getElementById('chat-message-input').onkeypress = () => {
  sendIsTypingToUser()
  if (isNotTyping != undefined) clearTimeout(isNotTyping);
  isNotTyping = setTimeout(sendIsNotTyping, 900);
  };

  function sendIsTypingToUser(){
     if(!isTyping){
        console.log("IsTyping...........")
        isTyping = true
        }
     }
  function sendIsNotTyping(){
     console.log("Not Typing...........")
     isTyping = false
     }
<input id="chat-message-input" type="text" placeholder="Enter Message..." autofocus style="width: 50%; padding: 8px;">


3

有一个很棒的库插件叫做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
};

这是如何运作的:在文本区域输入时,会调用typingStarted并将typing设置为true,防止再次调用。 然后调用typingStopped,但只有在5000毫秒后才会调用包装在_.debounce中的函数,这是作为_.debounce的第二个参数给出的。但是,如果再次调用typingStopped,则会将倒计时重置为从任何位置开始的5000毫秒。由于每次输入都会调用typingStopped,因此只有在按键之间完整的5秒钟后才会执行typing = false。

3
     <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> 



<div data-lang="js" data-hide="false" data-console="true" data-babel="false" class="snippet">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code>    <!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>

简单的Javascript + HTML就足以实现这个功能。 - Sivananda Mandapati
我发现在我的浏览器中,onkeypress事件不包括退格、删除、箭头键或Shift键(但这可能不是问题)。 - Alexx Roche

1
您可以使用JQuery来处理按键事件,而不是使用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");
    }
});

2
我们如何将这个传递给其他人?我想这会显示我正在输入的活动。 - Darktwen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接