javascript 如何在react中设置contenteditable div中的光标位置

xt0899hw  于 2023-01-11  发布在  Java
关注(0)|答案(1)|浏览(269)

我正在尝试创建一个文本编辑器,我使用了一个contenteditable div,每当有人更改其中的文本时,我都想用strong元素 Package 所有新文本,并更改div的innerHTML
这是我尝试过的(我使用react/nextjs)

useEffect(() => {
    if (!divRef.current) return;

    let text = divRef.current.innerText;
    const htmlArray = text.split(" ").map((word) => {
      return `<strong style="color: red">${word} </strong>`;
    });
    text = htmlArray.join("");
    divRef.current.innerHTML = text;
  }, [text]);

这里的一切都按预期工作,但每次我键入字符时,光标都转到开头,文本向后呈现。我如何解决这个问题?我希望用户键入时光标停留在div的结尾

yhxst69z

yhxst69z1#

这是因为每次text发生变化时,都要更新contenteditable div的innerHTML。
您需要捕获实际位置,并在状态更改后使用Selection将其设置回去

useEffect(() => {
  if (!divRef.current) return;

  // Get the current cursor position
  let selection = window.getSelection();
  if (!selection.rangeCount) return;
  let range = selection.getRangeAt(0);
  let cursorPosition = range.startOffset;

  // Update the innerHTML
  let text = divRef.current.innerText;
  const htmlArray = text.split(" ").map((word) => {
    return `<strong data-id="hey" style="color: red">${word} </strong>`;
  });
  text = htmlArray.join("");
  divRef.current.innerHTML = text;

  // Get the new cursor position
  selection = window.getSelection();
  range = selection.getRangeAt(0);

  // Set the cursor position to the new position
  range.setStart(range.startContainer, cursorPosition);
  range.collapse(true);
  selection.removeAllRanges();
  selection.addRange(range);
}, [text]);

相关问题