How to make the tab key Insert a tab character in

2019-02-04 18:50发布

I'm building a simple text editor by setting contentEditable=true on a div (anyway i think that textarea behaves in the same way) and i have some problems with the tab key.

What i want is that when the user presses the tab key, the focus remain on the div and a tab character is added to the text.

I've solved the first part of the problem by calling preventDefault() on the event object on keydown and now the div doesn't lose the focus, but i don't know why i can't insert the character.

The entity code for the tab char is 	 but if i try to add this string to the innerHTML Firefox replace it with a simple space (not   just a white space). I also tried with \t but the result is the same.

So my question is, how can I insert a tab character in the text?

6条回答
手持菜刀,她持情操
2楼-- · 2019-02-04 19:20

I know this is a bit old, but this ended up working the best for me...

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);
    }
}
查看更多
smile是对你的礼貌
3楼-- · 2019-02-04 19:22

Since the answer that was supposedly correct didn't work for me, I came up with this solution I think would work for more people.

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

That code worked for me, but also make sure to include the white-space:pre-wrap attribute in your css. Hope this helped!

查看更多
可以哭但决不认输i
4楼-- · 2019-02-04 19:28

tabs and spaces are collapsed in html to one space unless in a <pre> tag or has white-space: pre in its style

查看更多
神经病院院长
5楼-- · 2019-02-04 19:29

The reason why you only see a simple space is because sequences of whitespace characters (except non-breaking spaces) are treated as a single space character inside divs. If you want the tab character to display in the way you expect you'll need to put it inside something like a <pre> element that renders whitespace as it is in the source HTML.

查看更多
神经病院院长
6楼-- · 2019-02-04 19:35

you can insert a span with white-space=pre and content tab. this is better done with ranges like this :

// 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>

查看更多
做自己的国王
7楼-- · 2019-02-04 19:35

I use this solution:

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

When working with editable code, a <pre> element does not need the last added css. keyup vs keydown and the position of e.preventDefault() may differ in browsers.

Note: I think binding the key-event or whatever from the whole document is to be avoided. I had strange problems with Safari / iOS desktop browsers with contenteditable elements and bubbling events.

查看更多
登录 后发表回答