xterm.js粘贴场景仅监听onData不触发onKey避免重复输入问题咨询
问题根源说明
- 之前粘贴失效是因为快捷键判断逻辑错误:
e.keyCode == 'v'写法有误,keyCode返回的是数字类型,V键对应的keyCode为86;同时你使用的document.execCommand已经被现代浏览器废弃,可用性和兼容性都很差。 - 重复输入的原因:xterm.js中常规单键输入会同时触发
onKey和onData两个事件,两个回调都向socket发送消息就会出现重复字符。
解决方案实现
1. 新增状态标记、修复自定义按键逻辑
首先新增状态标记区分处理场景,同时替换废弃的剪贴板API:
// 状态标记:是否正在处理粘贴操作 let isPasting = false; // 状态标记:当前输入是否已由onKey处理完成 let isKeyHandled = false; // 修复自定义按键事件处理 term.attachCustomKeyEventHandler(async function (e) { // Ctrl + Shift + C 复制 if (e.ctrlKey && e.shiftKey && e.keyCode === 67) { const selectText = term.getSelection(); if (selectText) { await navigator.clipboard.writeText(selectText); console.log('复制成功'); } // 返回false阻止事件继续冒泡 return false; } // Ctrl + Shift + V 粘贴 if (e.ctrlKey && e.shiftKey && e.keyCode === 86) { isPasting = true; const pasteText = await navigator.clipboard.readText(); if (pasteText) { // 把粘贴内容写入终端显示 term.write(pasteText); // 发送粘贴内容到后端 socket.emit('data', pasteText); } console.log('粘贴成功'); isPasting = false; return false; } return true; });
2. 调整onKey和onData的处理逻辑
仅在非粘贴场景下处理onKey事件,onData仅处理未被onKey覆盖的批量粘贴输入,避免重复触发:
term.onKey(function (ev) { // 粘贴场景下跳过onKey处理 if (isPasting) return; isKeyHandled = true; // 处理Ctrl+D断开连接逻辑,Ctrl+D对应的字符码为4 if (ev.key.charCodeAt(0) === 4) { socket.disconnect(); return; } // 发送普通按键内容 socket.emit('key', ev.key); // 异步复位标记,避免影响下一次输入 setTimeout(() => isKeyHandled = false, 0); }); term.onData(function(data) { // 已经由onKey处理过的单键输入直接跳过,仅处理未被onKey处理的批量粘贴内容 if (isKeyHandled || isPasting) return; // 处理右键粘贴、拖拽粘贴等非快捷键触发的粘贴场景 socket.emit('data', data); });
3. 可选优化:绑定xterm.js内置paste事件
如果需要兼容右键菜单粘贴、拖拽粘贴等场景,可以直接绑定内置的paste事件,逻辑更统一:
term.onPaste(function (e) { isPasting = true; const pasteText = e.clipboardData.getData('text/plain'); if (pasteText) { term.write(pasteText); socket.emit('data', pasteText); } isPasting = false; });
逻辑说明
- 所有单键输入、快捷键操作全部由
onKey处理,处理完标记isKeyHandled,onData直接跳过对应输入,避免重复 - 所有粘贴场景(快捷键粘贴、右键粘贴、拖拽粘贴)都单独标记
isPasting,onKey跳过处理,避免冲突 - 替换了已经淘汰的
document.execCommand接口,改用标准的navigator.clipboard和xterm.js内置API,兼容性更强
内容的提问来源于stack exchange,提问作者qingyuanfl
相关产品推荐
相关产品推荐

