You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js+Socket.io聊天项目:删除输入后‘typing...’提示未消失问题

问题描述

我正在开发一个基于Node.js和Socket.io的实时聊天项目,遇到如下问题:当在聊天框中输入内容后,未发送而是删除所有输入内容时,对方客户端仍持续显示‘typing...’提示。我无法定位代码中的错误位置,相关代码如下:

原Node.js代码

const express = require('express');
const socket = require('socket.io');

const app = express();
const server = app.listen(3000)

app.use(express.static('public'))

const io = socket(server);

io.on('connection', (socket) => {
    console.log(socket.id)

    socket.on('chat', data => {
        io.sockets.emit('chat', data)
    })
    socket.on('typing', data => {
        socket.broadcast.emit('typing', data)
    })
})

原前端JavaScript代码

const socket = io.connect('http://localhost:3000');

const sender = document.getElementById('sender');
const message = document.getElementById('message');
const submitBtn = document.getElementById('submitBtn');
const output = document.getElementById('output');
const feedback = document.getElementById('feedback');

submitBtn.addEventListener('click', () => {
    if (sender.value != '' && message.value != '') {
        socket.emit('chat', {
            message: message.value,
            sender: sender.value,
        });
        sender.disabled = true;
    }
})

socket.on('chat', data => {
    feedback.innerHTML = ''
    output.innerHTML += '<p><strong>' + data.sender + ' : </strong>' + data.message + '</p>'
    message.value = '';
})

message.addEventListener('keypress', () => {
    if (message.value.trim() != false) {
        socket.emit('typing', sender.value)
    }
    else {
        feedback.innerHTML = ''
    }
})

socket.on('typing', data => {
    feedback.innerHTML = '<p>' + data + ' typing...</p>';
})

问题原因分析
  1. 事件监听范围不足:原代码用keypress事件监听输入,该事件仅在按下可打印字符时触发,退格、删除等清空内容的操作不会触发最后一次判断,导致内容为空时无法通知对方停止显示typing提示。
  2. 判断逻辑错误:message.value.trim() != false的写法有误,空字符串''和布尔值false比较时结果为true,导致内容为空时仍会触发typing事件。
  3. 缺少停止输入的通知机制:仅在本地清空自己的feedback,没有通过Socket.io通知其他客户端清空提示。

修复方案及修改后代码

1. 后端添加停止输入事件监听

在Node.js代码中新增stopTyping事件的处理,用于广播停止输入的状态给其他客户端:

const express = require('express');
const socket = require('socket.io');

const app = express();
const server = app.listen(3000)

app.use(express.static('public'))

const io = socket(server);

io.on('connection', (socket) => {
    console.log(socket.id)

    socket.on('chat', data => {
        io.sockets.emit('chat', data)
    })
    socket.on('typing', data => {
        socket.broadcast.emit('typing', data)
    })
    // 新增停止输入事件
    socket.on('stopTyping', () => {
        socket.broadcast.emit('stopTyping')
    })
})

2. 前端修改输入监听逻辑

  • 替换keypress为input事件,覆盖所有内容变更场景(退格、删除、粘贴等)。
  • 修复判断逻辑,用trimmedVal !== ''判断内容是否为空。
  • 内容为空时发送stopTyping事件通知服务器。
  • 发送消息后也触发stopTyping,避免发送后仍显示typing提示。
  • 添加stopTyping事件监听,清空对方的typing提示:
const socket = io.connect('http://localhost:3000');

const sender = document.getElementById('sender');
const message = document.getElementById('message');
const submitBtn = document.getElementById('submitBtn');
const output = document.getElementById('output');
const feedback = document.getElementById('feedback');

submitBtn.addEventListener('click', () => {
    if (sender.value != '' && message.value != '') {
        socket.emit('chat', {
            message: message.value,
            sender: sender.value,
        });
        sender.disabled = true;
        // 发送消息后通知停止输入
        socket.emit('stopTyping');
    }
})

socket.on('chat', data => {
    feedback.innerHTML = ''
    output.innerHTML += '<p><strong>' + data.sender + ' : </strong>' + data.message + '</p>'
    message.value = '';
})

// 用input事件监听所有内容变化
message.addEventListener('input', () => {
    const trimmedVal = message.value.trim();
    if (trimmedVal !== '') {
        socket.emit('typing', sender.value)
    } else {
        // 内容为空时发送停止输入事件
        socket.emit('stopTyping');
    }
})

socket.on('typing', data => {
    feedback.innerHTML = '<p>' + data + ' typing...</p>';
})

// 监听停止输入事件,清空提示
socket.on('stopTyping', () => {
    feedback.innerHTML = '';
})

内容的提问来源于stack exchange,提问作者prf00

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 05:21:13