Как сделать так, чтобы клавиша табуляции вставляла символ табуляции в div contentEditable? - PullRequest
15 голосов
/ 10 февраля 2010

Я создаю простой текстовый редактор, устанавливая contentEditable=true для div (во всяком случае, я думаю, что textarea ведет себя так же), и у меня есть некоторые проблемы с клавишей табуляции.

Я хочу, чтобы, когда пользователь нажимал клавишу табуляции, фокус оставался на элементе div и символ табуляции добавлялся к тексту.

Я решил первую часть проблемы, вызвав preventDefault() для объекта события при нажатии клавиши, и теперь div не теряет фокус, но я не знаю, почему я не могу вставить символ.

Код объекта для символа табуляции - 	, но если я попытаюсь добавить эту строку в innerHTML Firefox, замените ее простым пробелом (не   просто пробел). Я также пытался с \t, но результат тот же.

Итак, мой вопрос, как я могу вставить символ табуляции в текст?

Ответы [ 6 ]

22 голосов
/ 21 августа 2015

Я знаю, что это немного устарело, но в итоге это работает лучше для меня ...

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 голосов
/ 23 марта 2016

Так как ответ, который якобы был правильным, не сработал для меня, я пришел к такому решению, которое, я думаю, подойдет для большего числа людей.

$(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 в ваш css. Надеюсь, это помогло!

11 голосов
/ 10 февраля 2010

табуляция и пробелы свернуты в html на один пробел, если не в теге <pre> или не имеет white-space: pre в своем стиле

7 голосов
/ 05 апреля 2017

Вы можете вставить диапазон с пробелом = 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>
7 голосов
/ 10 февраля 2010

Причина, по которой вы видите только простой пробел, заключается в том, что последовательности символов пробела (кроме неразрывных пробелов) обрабатываются как один пробел внутри div. Если вы хотите, чтобы символ табуляции отображался так, как вы ожидаете, вам нужно поместить его внутри чего-то вроде <pre> элемента, который визуализирует пробельные символы, как в исходном HTML, или внутри элемента с white-space: pre, установленным через CSS .

5 голосов
/ 26 сентября 2017

Я использую это решение:

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

При работе с редактируемым кодом элементу <pre> не требуется последний добавленный CSS. keyup против keydown и позиция в e.preventDefault () могут отличаться в браузерах.

Примечание: Я думаю, что следует избегать связывания ключевого события или чего-либо еще из всего документа. У меня были странные проблемы с браузерами Safari / iOS для настольных компьютеров с contenteditable элементами и всплывающими событиями.

...