键入另一个字符时如何插入一个字符

Posted

技术标签:

【中文标题】键入另一个字符时如何插入一个字符【英文标题】:How to insert a character(s) when another character is typed 【发布时间】:2021-09-01 08:46:31 【问题描述】:

假设我有一个纯 html 文本区域。我想要做的是我希望能够在输入字符时插入不同的字符。例如,我想在将< 输入到文本区域时插入<>。另外,如果可能的话,我希望能够在<> 之间移动光标。

这就是我现在所拥有的。不过,它仅在光标位于末尾时才有效。

let editing = document.querySelector("#editing");

const handler = (event) => 
  if (editing.value.endsWith("<")) 
    editing.value += ">";
    editing.setSelectionRange(editing.selectionStart - 1, editing.selectionStart - 1)
  


editing.addEventListener("propertychange", handler)
editing.addEventListener("input", handler)
&lt;textarea name="editing" id="editing"&gt;&lt;/textarea&gt;

【问题讨论】:

这是你要找的How to get the caret column (not pixels) position in a textarea, in characters, from the start? @CharlesBamford 确实如此,我会看到 event.data 有您正在寻找的信息,请查看 mdn 获取文档。也使用event.target 而不是editing,它会让你的处理程序可重用。 【参考方案1】:

有关非常相关的讨论,请参阅Use tab to indent in textarea,此答案基于该讨论。

下面的代码应该做你想做的事,通过捕获&lt;keydown 事件并将其替换为插入&lt;&gt;(覆盖当前选择的任何内容)并将光标移动到&lt; 之后:

const editing = document.querySelector("#editing");

editing.addEventListener('keydown', (e) => 
  if (e.key === '<') 
    e.preventDefault();
    const pos = editing.selectionStart;
    editing.value = editing.value.slice(0, pos) + '<>' +
      editing.value.slice(editing.selectionEnd);
    editing.selectionStart = editing.selectionEnd = pos + 1;
  
);

不幸的是,这种方法也会破坏编辑器的撤消堆栈。在 Chrome 上,您可以使用document.execCommand('insertText', false, '&lt;&gt;') 模拟输入&lt;&gt;。不幸的是,Firefox 不支持此功能,因此它不是一个很好的解决方案。

【讨论】:

哇,关于撤消堆栈的注释让我陷入了关于保留撤消堆栈的整个兔子洞。假设如果mdn 正确,execCommand 应该在 firefox 89 中修复。我不敢相信在不杀死撤消堆栈的情况下编辑 textarea 值的唯一方法是依赖已弃用的 api。

以上是关于键入另一个字符时如何插入一个字符的主要内容,如果未能解决你的问题,请参考以下文章

如何将一个字符串插入另一个字符串的中间? [复制]

如何解决文本输入中的文本光标在插入键入的字符后自动放置在输入末尾的问题?

MacOS:如何禁用重音字符输入

c语言中如何将一字符串插入另一个字符串中?

如何从一个表列中获取值,将它们与字符串连接并将它们插入另一个表中?

显示键入时键入的字符(即时)