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

Node.js中如何禁用终端键盘输入回显仍捕获按键事件?

解决方案

要实现临时禁用终端键盘回显但保留按键捕获功能,可以利用Node.js的终端输入流(process.stdin本身是tty.ReadStream实例)控制终端原始模式,同时实现disableKeyboard和enableKeyboard函数来切换状态。

以下是修改后的完整代码:

let originalStdinMode;

// 禁用键盘回显,开启原始模式以捕获按键
function disableKeyboard() {
  if (process.stdin.isTTY) {
    // 保存终端原始模式,开启raw模式(关闭输入回显,直接捕获每个按键)
    originalStdinMode = process.stdin.setRawMode(true);
    process.stdin.resume();
    process.stdin.setEncoding('utf8');
  }
}

// 恢复键盘正常输入和回显
function enableKeyboard() {
  if (process.stdin.isTTY && originalStdinMode !== undefined) {
    // 恢复终端原始模式
    process.stdin.setRawMode(originalStdinMode);
    process.stdin.pause();
    // 输出换行避免后续输入与现有文本重叠
    process.stdout.write('\n');
  }
}

const KHGO = {};

process.stdin.on('keypress', (str, key) => {
  // 处理Ctrl+C正常退出程序
  if (key.ctrl && key.name === 'c') {
    enableKeyboard();
    process.exit(0);
  }
  KHGO[key.name] = true;
  setTimeout(() => {
    KHGO[key.name] = false;
  }, 100);
});

async function spell(string, ms) {
  let skipped = false;
  const characterArray = string.split("");
  console.log("");
  
  // 进入spell逻辑时禁用键盘回显
  disableKeyboard();

  // 逐字符输出,按空格跳过剩余内容
  for (let i = 0; i < characterArray.length; i++) {
    process.stdout.write(characterArray[i]);
    if (!skipped) await sleep(ms);
    if (KHGO.space) {
      skipped = true;
      // 直接输出剩余所有字符
      process.stdout.write(characterArray.slice(i + 1).join(''));
      break;
    }
    KHGO.space = false;
  }

  // 等待空格按下以继续
  while(true) {
    if (KHGO.space) {
      KHGO.space = false;
      break;
    }
    await sleep(1);
  }

  // spell逻辑结束后恢复键盘正常状态
  enableKeyboard();
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

(async function(){
  await spell("Example text", 40);
  await spell("Example text2", 40);
})();

关键说明:

  • 终端模式控制:setRawMode(true)会让终端进入原始模式,此时输入的字符不会被回显,每个按键(包括特殊键)都会直接触发keypress事件。disableKeyboard保存原始模式,enableKeyboard负责恢复,实现临时控制。
  • 按键捕获:原始模式下process.stdin的keypress事件可正常捕获所有按键,你的KHGO对象逻辑可保留,用于记录按键状态。
  • 退出处理:添加Ctrl+C的处理逻辑,确保在原始模式下能正常退出程序,避免终端状态异常。
  • 跳过逻辑优化:按下空格时直接输出剩余所有字符,减少不必要的循环等待。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 17:44:52