Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to track caret/cursor in contenteditable?

I'd like to track the movement of the caret/cursor in a contenteditable. I'm not sure what's the best way to do this, though.

I'm currently listening for click, keydown, keyup. (keypress of course doesn't even fire for things like arrow keys or ctrl-x.)

While click works fine, the problem with keydown is that it's fired before the caret actually moves, so when I query the current document selection range, I get the old position and not the new one. But if I rely on keyup to get the updated position, it fires too late: the caret moves as soon as the key is pressed down, but the key is released an arbitrary time later.

This must be possible because things like CKeditor are able to do this. Any hints?

like image 998
Yang Avatar asked Jul 11 '12 22:07

Yang


People also ask

How do you set a caret cursor position in Contenteditable element div?

To set caret position at a specific position in contenteditable div with JavaScript, we select the text node that with the text we want the cursor to be at and set the caret position there. to add a contenteditable div. Then we write: const node = document.

What is a caret position?

In computing, caret navigation (or caret browsing) is a kind of keyboard navigation where a caret (also known as a 'text cursor', 'text insertion cursor', or 'text selection cursor') is used to navigate within a text document.

What is caret position in JavaScript?

Javascript - Caret Position The caret is where text goes when typing into a text block.


2 Answers

It's nice to read that people are talking about CKEditor :). I'm one of its developers and I haven't been working much on selection, but I'll try to help.

What I know is that we've got an internal selectionChange event. So when do we check if it changed? ... ... At least once per every 200ms :) See:

http://dev.ckeditor.com/browser/CKEditor/trunk/_source/plugins/selection/plugin.js#L39

We also check selection every time we know that it could have been changed (e.g. by the API or on keyup/mouseup or on native selectionchange - http://dev.ckeditor.com/browser/CKEditor/trunk/_source/plugins/selection/plugin.js#L554). So... pretty much all the time :) AFAIK we do some tricks, so it doesn't burn your CPU, but it's still heavy. However, if we did this, then it's the only possible way to have this working so nicely.

Unfortunately, selection handling is by far the worst task in wysiwygs world. It's so broken in all - old and new browsers. More than 75% LOC in the file I linked above are hacks and tricks. That's complete madness.

like image 139
Reinmar Avatar answered Oct 21 '22 23:10

Reinmar


In Mozilla and Opera, the nasty business of handling key and mouse events is your only option. Not only is it fiddly, it also doesn't cover every case: it's possible to change the selection via the edit and context menus (via Select All, for example). To cover that, you'd also need to add some kind of polling of the selection object.

However, in IE (all the way back to at least 5.5) and recent-ish WebKit, there is a selectionchange event that fires on the document whenever the selection changes.

document.onselectionchange = function() {
    alert("Selection changed!");
};

There is a chance that Mozilla will support it in the future: https://bugzilla.mozilla.org/show_bug.cgi?id=571294

like image 29
Tim Down Avatar answered Oct 22 '22 00:10

Tim Down