Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I find the cursor's pixel position in a ContentEditable?

I mean finding the top/left pixel position of the cursor, rather than the character offset.

The reason I want to do this is because I want to show a small tooltip-like div next to the cursor (think of the newer MS Word's floating formatting box) that follows the cursor as you type or click. I can use the mouse coordinates if the user clicks, but not sure how to do this for typing.

Is there a reliable way? If not for finding the top/left position of the cursor, then the alternative is to just find the top position for the line.

Sample code isn't 100% necessary, as long as the method works and is well-explained.

like image 296
David Tang Avatar asked Jan 24 '11 13:01

David Tang


People also ask

What is caret position in Javascript?

Javascript - Caret Position The mouse moves the cursor. Text fields use a caret to indicate where text is inserted. Left clicking the mouse typically sets the caret location.


2 Answers

try this

var cursorY = window.getSelection().getRangeAt(0).getBoundingClientRect().top;

cursorY is the cursor Y position in window.

A Selection object represents the range of text selected by the user or the current position of the caret.

Selection.getRangeAt() return a range object representing one of the ranges currently selected.

like image 168
Edye Chan Avatar answered Sep 30 '22 02:09

Edye Chan


This not really an answer but concepts to think about:

In contenteditable, everything consists of nodes just like anything else HTML, so you can get the node's position, the problem is where in the node you are (if it's text, you might be 100 characters inside the node). So you have to make your own single character nodes.

To get the position as someone types, you'd have to capture the onkeypress event, stop the propagation bubble, take the character they are asking for, stuff it in a node (maybe a span ala a "marker") and then insert that node. Then you'd calculate the exact position of that span/node by it's offsets.

You'll probably have to remove the span and replace it with just the character afterwards.

There is also the problem I've encountered where if you mess with the bubble events when scrolling is supposed to happen, the caret may go outside the viewport.

Optionally, and this might be a slightly better idea, instead of messing with the propagation, allow the browser to insert the character on it's own, then immediately insert a zero-width unicode character (invisible) in a span/node before or afterwards, and calculate it's position instead. Then yank out the markers either on the fly or when they pause typing.

Yup, it's that messy, sorry. If someone has a better way, I am all ears.

like image 21
ck_ Avatar answered Sep 30 '22 03:09

ck_