如何制作tab键在contentEditable div中插入制表符?

问题描述 投票:15回答:6

我正在通过在div上设置contentEditable=true来构建一个简单的文本编辑器(无论如何我认为textarea的行为方式相同)并且我对tab键有一些问题。

我想要的是,当用户按Tab键时,焦点保留在div上,并且标签字符将添加到文本中。

我通过在keydown上的事件对象上调用preventDefault()解决了问题的第一部分,现在div没有失去焦点,但我不知道为什么我不能插入字符。

tab char的实体代码是	,但如果我尝试将此字符串添加到innerHTML Firefox,则将其替换为一个简单的空格(而不是 只是一个空格)。我也试过\t但结果是一样的。

所以我的问题是,如何在文本中插入制表符?

javascript html contenteditable
6个回答
7
投票

您只看到一个简单空格的原因是因为空白字符序列(非破坏空格除外)被视为div中的单个空格字符。如果你希望标签字符以你期望的方式显示,你需要把它放在像<pre>元素这样的东西中,它在源HTML中呈现空白,或者在通过CSS设置white-space: pre的元素内。


22
投票

我知道这有点旧了,但这最终对我来说是最好的......

function onKeyDown(e) {
    if (e.keyCode === 9) { // tab key
        e.preventDefault();  // this will prevent us from tabbing out of the editor

        // now insert four non-breaking spaces for the tab key
        var editor = document.getElementById("editor");
        var doc = editor.ownerDocument.defaultView;
        var sel = doc.getSelection();
        var range = sel.getRangeAt(0);

        var tabNode = document.createTextNode("\u00a0\u00a0\u00a0\u00a0");
        range.insertNode(tabNode);

        range.setStartAfter(tabNode);
        range.setEndAfter(tabNode); 
        sel.removeAllRanges();
        sel.addRange(range);
    }
}

15
投票

由于那个被认为是正确的答案对我不起作用,我提出了这个解决方案,我认为这对更多人有用。

$(document).on('keyup', '.editor', function(e){
  //detect 'tab' key
  if(e.keyCode == 9){
    //add tab
    document.execCommand('insertHTML', false, '&#009');
    //prevent focusing on next element
    e.preventDefault()   
  }
});

该代码对我有用,但也要确保在你的CSS中包含white-space:pre-wrap属性。希望这有帮助!


11
投票

标签和空格在html中折叠为一个空格,除非在<pre>标记中或其样式中有white-space: pre


7
投票

您可以使用white-space = pre和content选项卡插入范围。使用这样的范围可以做得更好:

// adapted from http://stackoverflow.com/a/25943182/460084
function insertTab() {
  if (!window.getSelection) return;
  const sel = window.getSelection();
  if (!sel.rangeCount) return;
  const range = sel.getRangeAt(0);
  range.collapse(true);
  const span = document.createElement('span');
  span.appendChild(document.createTextNode('\t'));
  span.style.whiteSpace = 'pre';
  range.insertNode(span);
  // Move the caret immediately after the inserted span
  range.setStartAfter(span);
  range.collapse(true);
  sel.removeAllRanges();
  sel.addRange(range);
}

$(document).on('keydown', '.editor', function(e) {
  if (e.keyCode == 9) {
    insertTab();
    e.preventDefault()
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable=true style="border: solid" class='editor'></div>

5
投票

我使用这个解决方案:

$('[contenteditable]').on('keydown', function(e){
    if(e.keyCode == 9){
        e.preventDefault();
        document.execCommand('insertHTML', false, '&#009');
    }
}).css('white-space', 'pre-wrap');

使用可编辑代码时,<pre>元素不需要最后添加的css。 keyup vs keydown和e.preventDefault()的位置在浏览器中可能有所不同。

注意:我认为应该避免绑定关键事件或整个文档中的任何内容。我在Safari / iOS桌面浏览器中遇到了奇怪的问题,这些浏览器具有令人满意的元素和冒泡事件。

© www.soinside.com 2019 - 2024. All rights reserved.