DEV Community

loading...

How do you detect what line it is in wrapped text elements?

Arnav Bansal
I slay dragons—or take them as pets.
・1 min read

I'm implementing a custom editor that uses rows of contenteditable divs. I'm having trouble implementing the right behavior for the 'up' or 'down' key.

When the 'up' key is pressed, I need to detect whether the caret is on the first line of text, and move the caret to the div above. Likewise for the 'down' key and the last line of text.

Thanks!

Discussion (7)

Collapse
erikwhiting88 profile image
Erik W

Hi Arnav. I'm not at a computer right now to see if this will work but I have an idea.

is the size of your div static? if so, maybe you can figure out how many characters your input gets to before it goes to the next line, and then check the string location of your cursor. for example, say you can type 80 characters per line you can say something like

if (user_input == KEY.up) {
  if (cursor_location > 80) {
    // go up a line
  else { 
    // go up a div
  }
}

I hope this helps

Collapse
erikwhiting88 profile image
Erik W

hi Arnav, did you ever get this figured out?

Collapse
itsarnavb profile image
Arnav Bansal Author

Hey Erik! I did figure out a solution, for variable sized divs

getLinePosition = () => {
    let r = getSelection().getRangeAt(0);
    let s = document.createElement('span');
    r.insertNode(s);
    let top = ((s.offsetTop - s.parentNode.offsetTop) === 0);
    let bottom = ((s.offsetTop - s.parentElement.offsetTop + s.offsetHeight) >= s.parentElement.offsetHeight);
    s.parentNode.removeChild(s);
    return {top, bottom};
  }

This returns an object {top: Boolean, bottom: Boolean} which works just enough for my purpose.

It can be modified to return the exact line number too if needed. s.offsetTop-s.parentNode.offsetTop returns a number that's fontHeight*lineNumber, which when divided by font height returns the line number.

I'm sure there's a less messy way of doing this that doesn't require adding a span.

Apologies for not replying sooner!

Thread Thread
erikwhiting88 profile image
Erik W

looks great! is this running live anywhere?

Thread Thread
itsarnavb profile image
Arnav Bansal Author

Just deployed it. You can try the functionality here: laughing-gates-6a6364.netlify.com

If you press the up/down arrows, you move between the paragraphs (two separate contenteditable divs) only on the first and last lines.

(It's not a completely usable editor yet; still needs much fixing)

Thread Thread
erikwhiting88 profile image
Erik W

very nice. Is this mostly just an exercise or do you have plans for this kind of feature?

Thread Thread
itsarnavb profile image
Arnav Bansal Author

I'm developing a platform where I need an editor with some custom features. I felt the need to understand all the moving parts of an editor.

My platform: deeplink.space