jQuery установка позиции курсора в contenteditable div

старая версия вопроса ниже, после исследования больше, я решил перефразировать вопрос. Проблема, как и раньше, мне нужно сосредоточиться на contenteditable div, не выделяя текст, делая прямой фокус выделяет текст в Chrome.

Я понимаю, что люди решили эту проблему в текстовых областях, сбросив позицию курсора в текстовых областях. Как я могу сделать это с contenteditable элемент? Все плагины, которые я пробовал, работают только с textareas. Спасибо.

старая формулировка вопроса:

У меня есть contenteditable элемент, который Я хочу сосредоточиться, но только постольку, поскольку чтобы поместить курсор в элемент, а не выбор всё.

elem.trigger('focus'); с jquery выделяет весь текст целиком элемент в chrome. Firefox ведет себя правильно, установив курсор на перед текстом. Как я могу получить Chrome вести себя так, как я хочу, или возможно, фокус не то, что Я смотрю для.

спасибо всем.

5 ответов


демо: http://so.lucafilosofi.com/jquery-setting-cursor-position-in-contenteditable-div/

      <div id="editable" contentEditable="true">
            <h2>Lorem</h2> <p>ipsum dolor <i>sit</i> 
               amet, consectetur <strong>adipiscing</strong> elit.</p> Aenean.
        </div>

    <script type="text/javascript">
        $(function () {
            $('[contentEditable="true"]').on('click', function (e) {
                if (!$(this).hasClass('editing')) {
                    var html = $(this).html();
                    if (html.length) {
                        var range = rangy.createRange();
                        $(this).toggleClass('editing').html('<span class="content-editable-wrapper">' + html + '</span>');
                        var $last = $(this).find('.content-editable-wrapper');
                        range.setStartAfter($last[0]);
                        range.collapse(false);
                        rangy.getSelection().setSingleRange(range);
                    }
                }
            }).on('blur', function () {
                $(this).toggleClass('editing').find('.content-editable-wrapper').children().last().unwrap();
            });
        });
    </script>

возможно, я неправильно понимаю вопрос, но не будет ли следующее (при условии редактируемого <div> с идентификатором "редактировать")? Таймер существует, потому что в Chrome собственное поведение браузера, которое выбирает весь элемент, кажется, запускается после focus событие, тем самым переопределяя эффект кода выбора, если не отложено до тех пор, пока после события фокуса:

var div = document.getElementById("editable");

div.onfocus = function() {
    window.setTimeout(function() {
        var sel, range;
        if (window.getSelection && document.createRange) {
            range = document.createRange();
            range.selectNodeContents(div);
            range.collapse(true);
            sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
        } else if (document.body.createTextRange) {
            range = document.body.createTextRange();
            range.moveToElementText(div);
            range.collapse(true);
            range.select();
        }
    }, 1);
};

div.focus();

Да, это происходит потому, что вы воспользовались

elem.trigger('focus'); 

попробуйте использовать класс или определить элемент, на котором вы хотите, чтобы огонь событие.


мне удалось решить эту проблему после того, как немного покопался в DOM.

elm.focus();
window.getSelection().setPosition(0);

вероятно, он работает только в браузерах WebKit, но поскольку это единственный источник проблемы, я добавил условное (используя jQuery)

if(!$.browser.webkit) {
    elm.focus();
} else {
    elm.focus();
    window.getSelection().setPosition(0);
}

надеюсь, что это решит вашу проблему.


установить положение указателя в теге pre или div:

function setCursor(pos) {
    var el = document.getElementById("asd");
    var range = document.createRange();
    var sel = window.getSelection();
    range.setStart(el.childNodes[0], pos);
    range.collapse(true);
    sel.removeAllRanges();
    sel.addRange(range);
    el.focus();
}

$('button').click(function () {
    setCursor(5);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="asd" contenteditable="true" >
asd
two
</div>
<button>Set caret position</button>

источник: https://social.msdn.microsoft.com/Forums/en-US/f91341cb-48b3-424b-9504-f2f569f4860f/getset-caretcursor-position-in-a-contenteditable-div?forum=winappswithhtml5