在正常视图和代码视图之间切换时保持光标位置

7
在Summernote中切换到代码视图时,光标总是移动到文档的末尾。有没有办法在切换时保持光标位置?有时使用它的人想写一些自定义HTML,因为这比使用编辑器的按钮更快,但是在切换到代码视图后,他们必须向上滚动并尝试找到之前的位置。这不太实用。
这里有一个简单的stackblitz
基本上,我需要实现的是:当光标在这里enter image description here时,我想点击“代码视图”按钮并跳转到这里enter image description here

https://github.com/summernote/summernote/issues/3125 - x00
@x00 这是一个类似的问题,但没有提供解决方案。 - igg
抱歉,无能为力。我尝试获取note-editable中的光标位置并将其镜像到note-codable,但这并不容易。我从来没有达到一对一的对应点。光标始终会偏差几个符号。而且你需要在相反的方向上镜像光标-从 note-codablenote-editable-这我甚至都没试过。因此,我只发布了一个可以指导你正确方向的链接。 - x00
如果你的解决方案“差几个符号”,那其实已经很好了。我不需要100%的准确性,我的主要问题是用户必须向上滚动才能找到他们输入的内容。与他们之前输入的位置“足够接近”将是一个明显的改进。请在Stackblitz上发布你的解决方案! - igg
我建议先查看它们所在的段落,并将光标放在该段落的开头作为一种临时解决方案。 - Tschallacka
1个回答

3
我在评论区回答了您的问题,但是我的回答不完整含有错误
 function getCaretCharacterOffsetWithin(element) {
     var caretOffset = 0;
     var doc = element.ownerDocument || element.document;
     var win = doc.defaultView || doc.parentWindow;
     var sel;
     if (typeof win.getSelection != "undefined") {
         sel = win.getSelection();
         if (sel.rangeCount > 0) {
             var range = win.getSelection().getRangeAt(0);
             var preCaretRange = range.cloneRange();
             preCaretRange.selectNodeContents(element);
             preCaretRange.setEnd(range.endContainer, range.endOffset);
             caretOffset = preCaretRange.toString().length;
         }
     } else if ( (sel = doc.selection) && sel.type != "Control") {
         var textRange = sel.createRange();
         var preCaretTextRange = doc.body.createTextRange();
         preCaretTextRange.moveToElementText(element);
         preCaretTextRange.setEndPoint("EndToEnd", textRange);
         caretOffset = preCaretTextRange.text.length;
     }
     return caretOffset;
 }

 $(document).ready(function() {
   $('#summernote').summernote({
       callbacks: {
         onKeydown: function(e) {
           const editable = document.getElementsByClassName('note-editable')[0]
           const pos = getCaretCharacterOffsetWithin(editable)
           console.log(pos)
           const codable = document.getElementsByClassName('note-codable')[0]
           codable.setSelectionRange(pos,pos)
         }
       }
   })
   $('#summernote').summernote('fullscreen.toggle');
 });

getCaretCharacterOffsetWithin的功劳归功于Tim Down

getCaretCharacterOffsetWithin()可以获取在.note-editable中光标的位置,但不是完全准确的,而且当你来回移动段落边界时,该值甚至不一致(正如Tim在他的原始帖子中警告的那样)。

setSelectionRange(pos,pos)将在.note-editable中的位置镜像到.note-codable中。

另外

  1. 你需要在切换到代码视图并返回之前才会开始工作。并修复这个问题。
  2. 您需要设置鼠标回调等内容以在鼠标单击等事件上镜像光标位置。现在它只在onKeydown上工作。
  3. 您需要滚动到textarea中的光标位置

这里是https://js-pvbgkh.stackblitz.io


谢谢,我觉得这个很有用。我会将悬赏保持开放几天,以防其他人能提供更好的解决方案。如果没有其他回答,我将授予你悬赏。 - igg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接