如何在onclick事件处理程序中的CKEDITOR.inline之后恢复插入符号位置

时间:2019-05-22 10:49:55

标签: ckeditor wysiwyg ckeditor4.x

我正在尝试在onclick事件中初始化CKEditor实例。 但我有一个问题,那就是当它只是一个div(可编辑内容)时,我可以单击它,而插入符号将位于我单击的位置。 但是,当CKEditor.inline函数执行其工作时,它将插入符号移动到容器的开头。我想保存CKEditor.inline之前的插入符位置,然后再设置。

我尝试了诸如window.getSelection()。anchor ...之类的解决方案...尝试了各种功能,这些功能可让我们保存插入符号的位置并进行还原,但没有效果。 也许有某种方法可以通过其本机命令获取anchorNode / anchorOffset / selectionStart并将其设置为CKEditor?

<div id="editor">
  <p>Hello my name is ...</p>
  <p>I am from ...</p>
  <p>London is the capital of Great Britain</p>
</div>
const editor = document.getElementById('editor');
  let isActivated = false;
  let isContenteditable = false;

  editor.onmouseenter = function(e) {
    if (!isContenteditable) {
      isContenteditable = true;
      editor.setAttribute('contenteditable', true);
    }
  };

  editor.onclick = function(e) {    
    if (!isActivated) {
      isActivated = true;
      const cke = CKEDITOR.inline('editor');

      cke.on('instanceReady', () => {
         // trying to set caret here
      });
    }
  }

不知道如何通过CKEditor初始化传递插入符号。 强制性的条件是初始化不应该在页面加载时进行,因为一页上有很多编辑器,并且不需要全部初始化。会落后

使用https://cdn.ckeditor.com/4.11.4/standard/ckeditor.js

PLAYGROUND -错误重现https://codepen.io/medinsky/pen/zQpBJQ?editors=1010

1 个答案:

答案 0 :(得分:0)

找到了一种解决方法,但这似乎不是很好。

还有其他想法吗?

https://codepen.io/medinsky/pen/Gaymxb?editors=0010

const isInRange = (position, start, end) => position >= start && position <= end;

function setCaretPosition(el, sPos) {
  let charIndex = 0;
  const range = document.createRange();
  range.setStart(el, 0);
  range.collapse(true);
  const nodeStack = [el];
  let node,
    foundStart = false,
    stop = false;

  while (!stop && (node = nodeStack.pop())) {
    if (node.nodeType === Node.TEXT_NODE) {
      const nextCharIndex = charIndex + node.length;
      if (!foundStart && isInRange(sPos, charIndex, nextCharIndex)) {
        range.setStart(node, sPos - charIndex);
        foundStart = true;
      }
      if (foundStart && isInRange(sPos, charIndex, nextCharIndex)) {
        range.setEnd(node, sPos - charIndex);
        stop = true;
      }
      charIndex = nextCharIndex;
    } else {
      let i = node.childNodes.length;
      while (i--) {
        nodeStack.push(node.childNodes[i]);
      }
    }
  }
  const selection = window.getSelection();
  selection.removeAllRanges();
  selection.addRange(range);
}

const editor = document.getElementById('editor');
let isActivated = false;

editor.onclick = function(e) {

  if (!isActivated) {
    editor.setAttribute('contenteditable', true);

    const {anchorNode, anchorOffset} = window.getSelection();
    if (anchorNode && anchorOffset) {
       anchorNode.parentElement.setAttribute('data-bookmark', anchorOffset.toString());
    }

    isActivated = true;
    const cke = CKEDITOR.inline('editor', {
      extraAllowedContent: "*[data-bookmark]"
    });

    cke.on('instanceReady', () => {
      const bookmarkElement = cke.container.$.querySelector('[data-bookmark]');

      if (bookmarkElement) {
        const bookmarkOffset = bookmarkElement.dataset.bookmark;

        if (bookmarkOffset) {
          bookmarkElement.removeAttribute('data-bookmark');
          setCaretPosition(bookmarkElement, bookmarkOffset);
        }
      }
    });

  }
}