Установка позиции каретки на пустой node внутри элемента contentEditable
Моя задача - установить текстовую привязку для отображения внутри пустого интервала node в пределах contentEditable
div.
В Firefox 3.6 не возникает никаких проблем:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="js/jquery-1.4.3.min.js">
</script>
<style>
#multiple {
border: 1px solid #ccc;
width: 800px;
min-height: 20px;
padding: 5px;
outline: none;
}
</style>
<script>
$(document).ready(function(){
var contentEditable = document.getElementById('multiple');
var lastItem = contentEditable.getElementsByTagName('span').item(2);
var selectElementText = function(el, win){
win = win || window;
var doc = win.document, sel, range;
if (win.getSelection && doc.createRange) {
range = doc.createRange();
range.selectNodeContents(el);
range.collapse(false);
sel = win.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
else
if (doc.body.createTextRange) {
range = doc.body.createTextRange();
range.moveToElementText(el);
range.select();
}
}
contentEditable.focus();
selectElementText(lastItem);
});
</script>
<title>Range Selection Tasks (Make Me Want to Cry)</title>
</head>
<body>
<div id="multiple" contentEditable="true">
<span style="color:red">First</span><span style="color:green">Second</span><span style="color:blue"></span>
</div>
</body>
</html>
... но в Webkit и IE основное внимание уделяется предпоследнему диапазону. Не знаю, почему. Он работает, если я помещаю пробел в последний интервал, но затем я получаю выбор из одного символа.
Сказав, что допустимо иметь пробел в последнем node, если каретка находится в самом начале.
Любая помощь с этим будет очень признательна. Заранее благодарю вас.
Ответы
Ответ 1
Модель выбора/диапазона IE основана на индексах в текстовом контенте, не обращая внимания на границы элементов. Я считаю, что невозможно установить фокус ввода внутри встроенного элемента без текста. Конечно, с вашим примером я не могу установить фокус внутри последнего элемента, нажав или клавиши со стрелками.
Это почти работает, если вы установите каждый интервал на display: block
, хотя все еще есть очень странное поведение, зависящее от существования пробела в родительском. Взломать дисплей, чтобы он выглядел inline с помощью трюков, таких как float, inline-block и абсолютное положение, делает IE обрабатывать каждый элемент как отдельное поле редактирования. Относительно расположенные элементы блока рядом друг с другом работают, но это, вероятно, непрактично.
Если вам станет легче, IE9, наконец, устранит эту неприятность и примет модель стандартного диапазона. (Ура!)
допустимо иметь пробел в последнем node, если каретка находится в самом начале.
Я бы, наверное, сделал это, если эксперт по выбору IE не может думать о чем-то лучше. (Вызов Tim Down!)
Ответ 2
Задайте элементу innerHTML
знак нулевой ширины:
('element').innerHTML = 'ÈB';
Теперь картер может туда поехать.
Ответ 3
Я нашел обходное решение для Webkit, не знаю, нашел ли кто-нибудь это раньше, но вместо программного добавления пространства с нулевой шириной вы можете сделать то же самое с содержимым содержимого css3 в после псевдоселектора элементов вы хотите включить каретку. Это имеет то преимущество, что дополнительные символы не отображаются в DOM, и пользователь не может перемещаться между ними. Поэтому в основном это не требует очистки.
Для этого для любого дочернего элемента редактируемого элемента контент будет выглядеть примерно так:
#mycontenteditableelement *:after {
content: '\200B';
}
Я не проверял полностью, но я подозреваю, что это полное обходное решение.
Ответ 4
Применение минимальной высоты и минимальной ширины к элементам внутри contenteditable с встроенным блоком может принести пользу, хотя воздействие имеет непредвиденные побочные эффекты:
#multiple * {
min-height: 1em;
}
span, b, strong, i, em, a, etc {
display: inline-block;
min-width: 1em;
background-color: hsla(0, 50%, 50%, .5); /* this is only a visual aid; discard @ will */
vertical-align: middle; /* so elements w/ inline-block align w/ text correctly */
}
Вы обнаружите, что все еще есть проблемы, но если вы готовы пожертвовать некоторыми проблемами для меньшего множества других, это может быть полезно.
Ответ 5
Для меня настройка содержания contenteditable div на <br>
работает. Я попытался установить его на nbsp;
, но это создает дополнительное пространство символов в div до начала редактирования.
Надеюсь, что это поможет.