Eric_Kim
Eric_Kim

Reputation: 31

Placing caret to the next children of contenteditable div

I am currently making a wysiwyg style editor using contenteditable div.

The div has children which are span tags.

This div initially has a single span without no text like below.

<div><span></span></div>

And then if I input text, "Hi, Hello World!" and apply "bold" on Hello.

Then, the html structure of the contenteditable div looks like below. I coded it and this is not a default contenteditable value.

<div
     data-block-id="8e809118-ffd8-48e7-b875-afbffd8241cf" 
     class="EditableBlock__Self-sc-7qskqk-0 fOnYdI"
     contenteditable="true"
>
  <span>Hi, </span>
  <span style="font-weight: 700;">Hello</span>
  <span> World!</span>
</div>

⠀⠀⠀⠀⠀⠀⠀⠀⠀

Issue

The problem is that I have a caret moving problem.

  1. When I try to move caret to the end of the focused sentence by pressing command + arrow left or command + arrow right. It doesn't work as I think and the caret is stuck inside of a current single span and not to move to next span.

    issue 1 gif image

  1. When I try to skip some words and move caret to next word by pressing option + arrow left or option + arrow right. It works but I have to press those keys one more time to move from current span to the next sibling span.

I googled some resources but most of them not directly related to this issue and old.

For your information, those two issues are not occurred when the contenteditable div only has one child span.

I had to manually handle document.selection and range when I used the contenteditable div.

I am wondering that I have to manually handle caret again to solve this issue?

Thank you for reading this long question and it would be appreciated if you share any ideas about this.

Upvotes: 2

Views: 525

Answers (2)

Sven Flossmann
Sven Flossmann

Reputation: 1

Actually, I had the same issue. Tried to use the proposal by Eric_Kim but without success.

I figured out that the cursor movement is correct in case the focus is on the parent (the <div>-element). Thus, it helped to ensure the focus is forced to set to the parent element in case the child gets it.

In react this would look like:

const divRef = useRef<HTMLDivElement>(null);

function handleFocus(e: FocusEvent){
  divRef.current?.focus();
}

<div contentEditable suppressContentEditableWarning onFocus={handleFocus} ref={proposalDivRef}>
  <span>text 1</span>
  <span>text 2</span>
</div>

Upvotes: 0

Eric_Kim
Eric_Kim

Reputation: 31

I've solved this issue by just change css display property to block from flex.

Upvotes: 1

Related Questions