Get and set cursor position with contenteditable div

前端 未结 4 1888
星月不相逢
星月不相逢 2020-12-25 13:58

I have a contenteditable div which I would like to be able to have users insert things such as links, images or YouTube videos. At the moment this is what I have:

4条回答
  •  渐次进展
    2020-12-25 14:07

    I have tried to find a solution,

    With a little help it can be perfected. It is a combination of answers I've found on SO, and my exp.

    Its tricky, its messy... but if you must, you can use it but it requires a bit of work to support inner links (if you cursor is on an anchor it will create anchor inside anchor)

    Here's the JS:

    var lastPos;
    var curNode = 0;
    function setCaret() {
      curNode=0;
      var el = document.getElementById("editor");
      var range = document.createRange();
      var sel = window.getSelection();
    
      console.log(el.childNodes);
      if (el.childNodes.length > 0) {
          while (lastPos > el.childNodes[curNode].childNodes[0].textContent.length) {
          lastPos = lastPos - el.childNodes[curNode].childNodes[0].textContent.length;
          curNode++;
    
          }
          range.setStart(el.childNodes[curNode].childNodes[0], lastPos);
          range.collapse(true);
          sel.removeAllRanges();
          sel.addRange(range);
      }
      el.focus();
    };
    
    
    function savePos() {
      lastPos = getCaretCharacterOffsetWithin(document.getElementById('editor'));
    }
    
    function addLink() {
      console.log(lastPos);
    
      setCaret();
      console.log(getCaretCharacterOffsetWithin(document.getElementById('editor')));
    
      console.log('focus');
    
      // $("#editor").focus();
      var link = $('#url').val();
      document.execCommand('createLink', false, link);
    
    }
    
    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;
    }
    

    fiddle

提交回复
热议问题