如何在TinyMCE React中修改后重新选择相同的文本

问题描述 投票:0回答:1

我正在尝试使用 Shift + F3 将 Microsoft Word 中提供的大小写更改功能实现到 TinyMCE React 编辑器中。我遇到的问题是最后一部分,它应该保持选择/突出显示相同的文本。只要我没有突出显示节点的最后一个字符,下面的代码就可以正常工作。如果我选择了行尾,则会收到错误:

Uncaught DOMException: Index or size is negative or greater than the allowed amount

到目前为止我有以下内容:

const handleCaseChange = (ed: Editor) => {
   ed.on("keydown", (event: KeyboardEvent) => {
      if (event.shiftKey && event.key === "F3") {
         event.preventDefault();
         const selection = ed.selection.getSel();
         const selectedText = selection?.toString();
         const startOffset = selection?.getRangeAt(0).startOffset;
         const endOffset = selection?.getRangeAt(0).endOffset;

         if (selectedText !== undefined && selectedText.length > 0) {
            let transformedText;
            if (selectedText === selectedText.toUpperCase()) {
               transformedText = selectedText.toLowerCase();
            } else if (selectedText === selectedText.toLowerCase()) {
               transformedText = capitalizeEachWord(selectedText);
            } else {
               transformedText = selectedText.toUpperCase();
            }
            ed.selection.setContent(transformedText);
            const range = ed.getDoc().createRange();

            // This is what's currently erroring
            range.setStart(selection.anchorNode, startOffset);

            if (endOffset === selection?.anchorNode?.textContent?.length) {
               range.setEndAfter(selection.anchorNode);
            } else {
               range.setEnd(selection.anchorNode, endOffset);
            }
            selection.removeAllRanges();
            selection.addRange(range);
         }
      }
   }
}
const capitalizeEachWord = (str: string) => str.replace(/\b\w/g, (char: string) => char.toUpperCase());

我还可以在

range.setStart
中尝试什么才能使其正常工作?

tinymce selection tinymce-react
1个回答
0
投票

我从 TinyMCE 文档中找到了一个简单的解决方案 - Selection.getBookmark()

获取书签

返回当前选择的书签位置。然后,在对文档进行一些内容修改后,可以使用此书签对象来恢复选择。

我尝试了以下方法,它可以更改大小写,然后将新内容标记为选中。

const handleCaseChange = (ed: Editor) => {
   ed.on("keydown", (event: KeyboardEvent) => {
      if (event.shiftKey && event.key === "F3") {
         event.preventDefault();
         const selection = ed.selection.getSel();
         const selectedText = selection?.toString();

         if (selectedText !== undefined && selectedText.length > 0) {
            let transformedText;
            if (selectedText === selectedText.toUpperCase()) {
               transformedText = selectedText.toLowerCase();
            } else if (selectedText === selectedText.toLowerCase()) {
               transformedText = capitalizeEachWord(selectedText);
            } else {
               transformedText = selectedText.toUpperCase();
            }

            const bookmark = ed.selection.getBookmark();
            ed.selection.setContent(transformedText);
            ed.selection.moveToBookmark(bookmark);
         }
      }
   }
}
const capitalizeEachWord = (str: string) => str.replace(/\b\w/g, (char: string) => char.toUpperCase());
© www.soinside.com 2019 - 2024. All rights reserved.