首页 > 解决方案 > 插入 4 个空格而不是制表符

问题描述

我在其中有一个contenteditable divwith divs,如下所示:

<div id="wrapper" contenteditable=true onkeydown="preventTab(event);">
  <div id="line1" class="line"></div>
  <div id="line2" class="line"></div>
  <div id="line3" class="line"></div>
  <div id="line4" class="line"></div>
</div>

使用 CSS,使用::beforefor line numbers ,这看起来像这样:

例子

现在,我想,每当有人按下制表符时,它会自动插入四个空格而不是制表符。我得到了这个函数,但它在触发事件后什么都不做。

function preventTab(event) {

    event = event || window.event;

    if (event.keyCode === 9) {

        // for loop, so the user can set the amount of spaces they want.
        for (let i = 0; i < tabSize; i++) {
            let e = new KeyboardEvent("keydown", {
                bubbles: true,
                code: "Space",
                key: " ",
                keyCode: 32
            });

            event.target.dispatchEvent(e);
        }

        event.preventDefault();
    }
}

正如我所说,什么都没有发生(也许是因为isTrusted: false?),也没有抛出任何错误。
顺便说一句,我注意到这个标题相同的问题,但这在很大程度上取决于 jQuery 库,我正在寻找一种纯 JavaScript 方法。

标签: javascripthtml

解决方案


模拟点击和击键被认为是一种安全风险。根据W3C UI 事件工作草案

“大多数不受信任的事件不会触发它们的默认操作……”

相反,您可以使用我在此片段中演示的选择范围contenteditable=true来操作元素的内容。

let tabSize = 2;
let spaces = '';
for (i = 0; i < tabSize; i++) {
  spaces += ' ';
}

document.getElementById('editor').addEventListener('keydown', preventTab);

function preventTab(event) {
  if (event.keyCode === 9) {
    event.preventDefault();
    let selection = window.getSelection();
    selection.collapseToStart();
    let range = selection.getRangeAt(0);
    range.insertNode(document.createTextNode(spaces));
    selection.collapseToEnd();
  }
}
html,
body {
  height: 100%;
  width: 100%;
  margin: 0;
}

#editor {
  width: 100%;
  height: 100%;
  font-family: monospace;
  white-space: pre;
}
<div id="editor" contenteditable=true></div>


推荐阅读