How to set cursor position in an editable element?

4

I have the following structure:

<pre id="editor" contenteditable="true">
“Always pass on what you have learned.” - Yoda

> {|}

--
X    
</pre>

I want when someone clicks a button I put the cursor in place of {|} . This {|} text actually exists in my element, I can replace it with an html element if necessary.

How can I set the position of the cursor so that when I start typing my text it appears there in that position?

    
asked by anonymous 25.12.2013 / 00:55

2 answers

5

You need to use the Range and Selection objects to get a selected range within the element:

// marca lugar para posicionar o cursor em 'editor'
var marker = '{|}';

// cria intervalo
var range = document.createRange();
var index = editor.innerText ? editor.innerText.indexOf(marker) : editor.textContent.indexOf(marker);
range.setStart(editor.childNodes[0], index);
range.setEnd(editor.childNodes[0], index + marker.length);

// faz seleção
var selection = window.getSelection();
selection.addRange(range);

editor.focus();

Fiddle here .

    
25.12.2013 / 02:13
2

As Jordan has already replied, with a good response by the way, you can find the text inside the editor.

However, using childNodes[0] will not work if there are html tags within the editor that encompass the cursor marker. See an example in this jsfiddle , whose HTML is:

<pre id="editor" contenteditable="true">
“Always pass on what you have learned.” - Yoda
<div>
> {|}
</div>

--
X    
</pre>

I've prepared a version using an HTML tag with a special% wrapper that avoids this problem and still allows you to position the cursor without needing a visual element.

The code looks like this:

function setCursor(node, cursorElement) {
    var range = document.createRange();
    range.setStart(cursorElement, 0);
    range.collapse(true);
    if (window.getSelection) {
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
        node.focus();
    } else if (document.selection && range.select) {
        range.select();
    }
}

var editor = document.querySelector("#editor");
var button = document.querySelector("button");

button.addEventListener("click", function(e) {
    setTimeout(function () {
        setCursor(editor, document.querySelector("#cur"));
    }, 200);
}, false);

The marker is a id tag, as in the following snippet:

<pre id="editor" contenteditable="true">
“Always pass on what you have learned.” - Yoda

> <span id="cur"/>

--
X    
</pre>

See the Jsfiddle .

    
25.12.2013 / 03:34