【问题标题】: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;

【问题讨论】:

标签: javascript html


【解决方案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。
猜你喜欢
  • 2012-09-25
  • 2015-02-11
  • 2012-08-14
  • 2013-11-24
  • 1970-01-01
  • 2020-04-22
  • 2011-05-13
  • 2013-03-04
相关资源
最近更新 更多