代码之家  ›  专栏  ›  技术社区  ›  mck89

如何使tab键在contenteditable div中插入tab字符?

  •  14
  • mck89  · 技术社区  · 14 年前

    我正在通过设置 contentEditable=true 在一个DIV上(无论如何,我认为TEXTARIA的行为方式是相同的),我对TAB键有一些问题。

    我想要的是,当用户按下tab键时,焦点仍停留在DIV上,文本中会添加一个tab字符。

    我打电话解决了问题的第一部分 preventDefault() 在keydown上的事件对象上,现在DIV不会失去焦点,但我不知道为什么不能插入字符。

    选项卡字符的实体代码为 	 但是如果我尝试将这个字符串添加到innerhtml firefox,请用一个简单的空格替换它(不是   只是一个空白)。我也试过 \t 但结果是一样的。

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

    6 回复  |  直到 5 年前
        1
  •  7
  •   Tim Down    5 年前

    之所以只看到一个简单的空格,是因为空白字符序列(不间断空格除外)被视为div中的单个空格字符。如果希望标签字符以预期的方式显示,则需要将其放入类似 <pre> 元素,该元素在源HTML中呈现空白,或在具有 white-space: pre 通过CSS设置。

        2
  •  22
  •   Michael Sabin    9 年前

    我知道这有点老,但这对我来说是最好的…

    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);
        }
    }
    
        3
  •  15
  •   Devplex    8 年前

    因为这个被认为是正确的答案对我不起作用,所以我想出了一个解决方案,我认为它对更多的人有用。

    $(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()   
      }
    });
    

    该代码对我有效,但也要确保包括 white-space:pre-wrap 属性。希望这有帮助!

        4
  •  11
  •   meouw    11 年前

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

        5
  •  7
  •   kofifus    7 年前

    您可以插入一个空白区域=pre和内容选项卡的范围。 这样的范围做得更好:

    // 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>
        6
  •  5
  •   Jonas Lundman    7 年前

    我使用这个解决方案:

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

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

    注: 我认为应该避免绑定关键事件或整个文档中的任何内容。我在Safari/iOS桌面浏览器中遇到了一些奇怪的问题,其中包含内容可编辑的元素和冒泡的事件。