最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to set cursor position on last child node of a contenteditable paragraph tag where the last child node is #text

programmeradmin0浏览0评论

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?

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论