Get contentEditable caret index position

后端 未结 10 873
暗喜
暗喜 2020-11-22 05:48

I\'m finding tons of good, crossbrowser anwers on how to SET the cursor or caret index position in a contentEditable element, but none on how to GET or find its

10条回答
  •  星月不相逢
    2020-11-22 06:15

    A straight forward way, that iterates through all the chidren of the contenteditable div until it hits the endContainer. Then I add the end container offset and we have the character index. Should work with any number of nestings. uses recursion.

    Note: requires a poly fill for ie to support Element.closest('div[contenteditable]')

    https://codepen.io/alockwood05/pen/vMpdmZ

    function caretPositionIndex() {
        const range = window.getSelection().getRangeAt(0);
        const { endContainer, endOffset } = range;
    
        // get contenteditableDiv from our endContainer node
        let contenteditableDiv;
        const contenteditableSelector = "div[contenteditable]";
        switch (endContainer.nodeType) {
          case Node.TEXT_NODE:
            contenteditableDiv = endContainer.parentElement.closest(contenteditableSelector);
            break;
          case Node.ELEMENT_NODE:
            contenteditableDiv = endContainer.closest(contenteditableSelector);
            break;
        }
        if (!contenteditableDiv) return '';
    
    
        const countBeforeEnd = countUntilEndContainer(contenteditableDiv, endContainer);
        if (countBeforeEnd.error ) return null;
        return countBeforeEnd.count + endOffset;
    
        function countUntilEndContainer(parent, endNode, countingState = {count: 0}) {
          for (let node of parent.childNodes) {
            if (countingState.done) break;
            if (node === endNode) {
              countingState.done = true;
              return countingState;
            }
            if (node.nodeType === Node.TEXT_NODE) {
              countingState.count += node.length;
            } else if (node.nodeType === Node.ELEMENT_NODE) {
              countUntilEndContainer(node, endNode, countingState);
            } else {
              countingState.error = true;
            }
          }
          return countingState;
        }
      }
    

提交回复
热议问题