Как заставить клавишу tab Вставлять символ табуляции в contentEditable div?
-
19-09-2019 - |
Вопрос
Я создаю простой текстовый редактор, установив contentEditable=true
в div (во всяком случае, я думаю, что textarea ведет себя точно так же), и у меня есть некоторые проблемы с клавишей tab.
Я хочу, чтобы, когда пользователь нажимает клавишу tab, фокус оставался на div, а в текст добавлялся символ табуляции.
Я решил первую часть проблемы, позвонив preventDefault()
на объекте event нажимаем keydown, и теперь div не теряет фокус, но я не знаю, почему я не могу вставить символ.
Код объекта для символа tab выглядит следующим образом 	
но если я попытаюсь добавить эту строку в innerHTML Firefox, замените ее простым пробелом (не
просто пробел).Я также пробовал с \t
но результат тот же.
Итак, мой вопрос в том, как я могу вставить символ табуляции в текст?
Решение
Причина, по которой вы видите только простой пробел, заключается в том, что последовательности пробелов (за исключением неразрывных пробелов) обрабатываются как один пробел внутри divs.Если вы хотите, чтобы символ табуляции отображался так, как вы ожидаете, вам нужно поместить его во что-то вроде <pre>
элемент, который отображает пробелы так, как они есть в исходном HTML, или внутри элемента с white-space: pre
устанавливается с помощью CSS.
Другие советы
Я знаю, что это немного устарело, но в итоге у меня получилось лучше всего...
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);
}
}
Поскольку ответ, который предположительно был правильным, не сработал для меня, я придумал это решение, которое, я думаю, сработало бы для большего количества людей.
$(document).on('keyup', '.editor', function(e){
//detect 'tab' key
if(e.keyCode == 9){
//add tab
document.execCommand('insertHTML', false, '	');
//prevent focusing on next element
e.preventDefault()
}
});
Этот код сработал для меня, но также не забудьте включить white-space:pre-wrap
атрибут в вашем css.Надеюсь, это помогло!
табуляции и пробелы сворачиваются в html до одного пробела, если только в <pre>
тег или имеет white-space: pre
в своем стиле
вы можете вставить интервал с пробелом=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>
Я использую это решение:
$('[contenteditable]').on('keydown', function(e){
if(e.keyCode == 9){
e.preventDefault();
document.execCommand('insertHTML', false, '	');
}
}).css('white-space', 'pre-wrap');
При работе с редактируемым кодом <pre>
элементу не нужен последний добавленный css. keyup
против keydown
и тот положение например,функция preventDefault() может отличаться в разных браузерах.
Примечание: Я думаю, следует избегать привязки ключевого события или чего-либо еще ко всему документу.У меня были странные проблемы с настольными браузерами Safari / iOS с элементами contenteditable и всплывающими событиями.