1

I am trying to send the caret at the end of a contenteditable, which works fine, except that it is not placed at the end if I insert an empty <span></span> element and the end.

<div contenteditable>
    <span>Start</span>
    <span></span>
</div>

The Caret is placed at Start, but not on the new line.
This is the code I am using to place the caret at the end:

PlaceCaretAtEnd(el) {
    el.focus();
    if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") {
        var range = document.createRange();
        range.selectNodeContents(el);
        range.collapse(false);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    } else if (typeof document.body.createTextRange != "undefined") {
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.collapse(false);
        textRange.select();
    }
}

Where el is the contenteditable div.

Thanks for your help.

Nihal
  • 5,262
  • 7
  • 23
  • 41
jjuser19jj
  • 1,637
  • 3
  • 20
  • 38

1 Answers1

0

You had some syntax errors on the snippet. I fixed them, ran it, and it worked. Caret is in the end.

However, I'm not exactly sure what you meant (if you want the caret at the end of the new line or the first line.)
In order for the caret to be at the end of the new line, you need to effectively "create" a new line. span is an inline element. span won't start a new line without some CSS rule. div will. Also, it needs sone content in order for it to take effect.

placeCaretAtEnd(document.querySelector("div[contenteditable]"));

function placeCaretAtEnd(el) {
    el.focus();
    if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") {
        var range = document.createRange();
        range.selectNodeContents(el);
        range.collapse(false);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    } else if (typeof document.body.createTextRange != "undefined") {
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.collapse(false);
        textRange.select();
    }
}
<div contenteditable>
    <span>Start</span>
    <span style="display: block;">New Line</span>
</div>

Something extra, contenteditable is a boolean attribute. you can omit the ="true" part and simply put the attribute. See this.

Edit:
If you want a new line without any text on it use <br> (twice - since span comes before it. If it was <div>Start</div> you could have used only 1)

placeCaretAtEnd(document.querySelector("div[contenteditable]"));

function placeCaretAtEnd(el) {
    el.focus();
    if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") {
        var range = document.createRange();
        range.selectNodeContents(el);
        range.collapse(false);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    } else if (typeof document.body.createTextRange != "undefined") {
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.collapse(false);
        textRange.select();
    }
}
<div contenteditable>
    <span>Start</span>
    <br><br>
    <span></span>
</div>
Maor Refaeli
  • 2,417
  • 2
  • 19
  • 33
  • Thanks for your help. You got it right. I want to place the caret at the beginning / end of the new line (it will be empty when I insert it). However when the new line is inserted it will be empty at first, even if I use the

    tag, the caret wont appear at the new line. Sorry if my description of the problem is not clear enough.

    – jjuser19jj Aug 27 '18 at 13:11
  • I edited my answer with another alternative, maybe now it's more helpful – Maor Refaeli Aug 27 '18 at 13:54