jquery Setting cursor position in contenteditable div

Mark picture Mark · May 20, 2010 · Viewed 63k times · Source

The old version of the question is below, after researching more, I decided to rephrase the question. The problem as before is, I need to focus a contenteditable div without highlighting the text, doing straight up focus highlights the text in Chrome.

I realize that people solved this problems in textareas by resetting the caret position in the textarea. How can I do that with a contenteditable element? All the plugins I've tried only works with textareas. Thanks.

Old Phrasing of the question:

I have a contenteditable element that I want to focus, but only insofar as to place the cursor at the front of the element, rather selecting everything.

elem.trigger('focus'); with jquery selects all the text in the entire element in chrome. Firefox behaves correctly, setting the caret at the front of the text. How can I get Chrome to behave the way I want, or is focus perhaps not what I'm looking for.

Thanks all.

Answer

Tim Down picture Tim Down · Jun 1, 2010

Maybe I'm misreading the question, but wouldn't the following do (assuming an editable <div> with id "editable")? The timer is there because in Chrome, the native browser behaviour that selects the whole element seems to trigger after the focus event, thereby overriding the effect of the selection code unless postponed until after the focus event:

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();