I want to set cursor position on the last child node of a paragraph contenteditable tag and the last child node is a #text node, hence the cursor position should be at the end of the text.
Given the paragraph node as below
<p contenteditable="true">
Node 1
<div>Node 2</div>
Node 3
<div>Node 4</div>
Node 5
</p>
I want to be able to set the cursor position at the end of Node 5, in order to do so I did the following below.
//function to sum the length of the the #text node text content
function sumAllTextNodeLengthInTreeAsOffset(tree: HTMLElement, childNodeIndex?: number | undefined) {
let sum = 0;
for(let i=0; i<(tree as HTMLElement).childNodes.length; i++) {
if(((tree as HTMLElement).childNodes[i] as HTMLElement).nodeType === 3) {
sum+=(((tree as HTMLElement).childNodes[i] as HTMLElement).textContent as string).length;
if(childNodeIndex !== undefined) {
if(i === childNodeIndex) {
break;
}
}
}
}
return sum;
}
Then I am using the function below to set cursor position
function setCursorPositionInContenteditableElement(el: HTMLElement, pos: number) {
const
selectedText = window.getSelection(),
selectedRange = document.createRange()
;
if(el.childNodes[0]) {
selectedRange.setStart(el.childNodes[0], pos);
}
else {
el.innerText = ' ';
selectedRange.setStart(el.childNodes[0], pos);
const time = setTimeout(() => {
el.innerText = '';
clearTimeout(time);
}, 0);
}
selectedRange.collapse(true);
selectedText?.removeAllRanges();
selectedText?.addRange(selectedRange);
el.focus();
}
If the last child node is #text node then set cursor position to the end of the last child below always fails, instead of setting cursor position to last child it sets the cursor position on the first child.
if((tree as HTMLElement).hasChildNodes()) {
if(
(
(tree as HTMLElement).childNodes[
(tree as HTMLElement).childNodes.length - 1
] as HTMLElement
).nodeType === 3
) {
setCursorPositionInContenteditableElement(
(tree as HTMLElement),
(tree as HTMLElement).children.length >= 1?
((tree as HTMLElement).childNodes.length - 1)
:
sumAllTextNodeLengthInTreeAsOffset(tree as HTMLElement)
);
(tree as HTMLElement).focus();
(tree as HTMLElement).click();
}
}
As shown in the images below:
I am trying to do the following
setCursorPositionInContenteditableElement(p, <index of the last child (which is a text node)>)
And the index of the last child from the image below is 10. instead of setting the cursor position at the end of <click here to continue new line> at node 10, the cursor is set at offset 10 of the first child of paragraph tag.
I have tried to sum all text node text content length up to the last child text content length to calculate the offset of the last child which is a text node, but setting the calculated offset causes error.
How can I solve this problem?