Подтвердить что ты не робот

Установка позиции каретки на пустой 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, если каретка находится в самом начале.

Любая помощь с этим будет очень признательна. Заранее благодарю вас.

4b9b3361

Ответ 1

Модель выбора/диапазона IE основана на индексах в текстовом контенте, не обращая внимания на границы элементов. Я считаю, что невозможно установить фокус ввода внутри встроенного элемента без текста. Конечно, с вашим примером я не могу установить фокус внутри последнего элемента, нажав или клавиши со стрелками.

Это почти работает, если вы установите каждый интервал на display: block, хотя все еще есть очень странное поведение, зависящее от существования пробела в родительском. Взломать дисплей, чтобы он выглядел inline с помощью трюков, таких как float, inline-block и абсолютное положение, делает IE обрабатывать каждый элемент как отдельное поле редактирования. Относительно расположенные элементы блока рядом друг с другом работают, но это, вероятно, непрактично.

Если вам станет легче, IE9, наконец, устранит эту неприятность и примет модель стандартного диапазона. (Ура!)

допустимо иметь пробел в последнем node, если каретка находится в самом начале.

Я бы, наверное, сделал это, если эксперт по выбору IE не может думать о чем-то лучше. (Вызов Tim Down!)

Ответ 2

Задайте элементу innerHTML знак нулевой ширины:

('element').innerHTML = '&#200B';

Теперь картер может туда поехать.

Ответ 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 до начала редактирования.

Надеюсь, что это поможет.