5

How can I place the caret (collapsed range) inside an empty element node. This code is supposed to work, but it doesnt.

node = document.getElementById('some-empty-strong-node')
range = document.createRange()
range.selectNodeContents(node)
window.getSelection().addRange(range)

Trying other tricks like adding an empty text node inside the element node or setting the range start inside the node and the range end somewhere else, and then collapsing the range also doesn't work. Anoyone has an Idea?

disc0dancer
  • 9,185
  • 11
  • 36
  • 46

3 Answers3

8

This is possible in Firefox and Opera, but impossible in both WebKit and IE <= 8.

WebKit has a long-standing bug to fix this: https://bugs.webkit.org/show_bug.cgi?id=15256 for the empty element case and https://bugs.webkit.org/show_bug.cgi?id=23189 for the general case of placing the caret at the start of a text node. Last I heard it's likely to be years before it's fixed.

IE <= 8 has all kinds of issues around selections, of which this is but one. IE 9 introduced DOM2 Range support and HTML5 Selection support and your code may well work in IE 9 (I can't test it right now).

Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • 1
    Already added my +1, but saw your edit and decided to test IE 9 quickly - it works. – Andy E Mar 30 '11 at 16:20
  • 2
    @Andy: Excellent, I thought it might. WebKit dragging its heels on this is getting quite annoying now: it's been three and a half years. – Tim Down Mar 30 '11 at 16:30
  • That explains it. I was trying it in chrome. Thank you. – disc0dancer Mar 30 '11 at 18:05
  • 4
    Another 3 years on, this bug still seems to be there! – Stuart Jan 14 '14 at 00:00
  • The contenteditable case remains to be fixed in chrome, bug filed [here](https://code.google.com/p/chromium/issues/detail?id=456917&thanks=456917&ts=1423511681). – simonzack Feb 09 '15 at 19:56
  • when hitting "enter" in a div inside a contenteditable div, chrome automatically creates a new div with a br inside it, with the cursor inside the new div. On entering text, the br automatically disappears (being replaced by the text). However if one hits "enter" again without typing any text, then the the br is retained. I'm not sure how the Chrome developers think that br automatically belongs within the empty div "paragraph", but if it isn't there then it is impossible to place the cursor within the div, even if an empty textnode is physically created in it. – Pancho Jun 24 '16 at 13:05
  • (while this may on the surface seem a small issue, sadly it is big enough so as to be forcing our business to abandon chrome as a browser) – Pancho Jun 24 '16 at 13:07
1

A trick to that is to use a placeholder (so it disapear when placing the caret). Worked for me with "display: inline" div on chrome.

.css

[invisibleplaceholder]:empty:before{
    content: attr(invisibleplaceholder);
    color: transparent;
    cursor: text;
}

[invisibleplaceholder]:empty:focus:before{
    content: "";
}

.html

<div id="div1" contenteditable="true" invisbleplaceholder="."></div>
<div id="div2" contenteditable="true" invisibleplaceholder="."></div>

.js

$("body").click(function(){
        var range = document.createRange();
        var sel = window.getSelection();
        var node = $('div2')[0]; //your node
        range.setStart(node, 0); //your position in node
        range.collapse(true);
        sel.removeAllRanges();
        sel.addRange(range);
    });
k3n
  • 11
  • 2
0

I found that if you do this for Chrome:

<div id="select-this-element"> <br style="content: no-close-quote;" /></div>

It will work the same way that works in Firefox and Opera.