首页 > 解决方案 > Javascript将插入符号移动到contenteditable中的搜索字符串

问题描述

我有一个内容可编辑的 div,我需要将插入符号移动到字符串的位置,但我不知道该怎么做。有没有人有什么建议?

<div id='mydiv' contenteditable='true'>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
    Sed eget libero sit <mark>amet</mark> and **peekabo** magna sagittis sagittis quis nec risus.
    Pellentesque feugiat pharetra purus id pharetra.
</div>

<script>
doFindStringAndMoveCaret('mydiv', 'peekabo');


function doFindStringAndMoveCaret(elem, searchFor) { 
    // Find searchFor string in the elem.innerHTML, and then move the 
    // cursor to the beginning of that text

    ??
}

理想情况下是普通的旧 javascript(不是 jQuery)

谢谢安倍

标签: javascriptcontenteditable

解决方案


function doFindStringAndMoveCaret(elem, text) {
  function setCurrentCursorPosition(element, chars) {
    element.focus()
    if (chars >= 0) {
      var selection = window.getSelection();

      range = createRange(element.parentNode, {
        count: chars
      });

      if (range) {
        range.collapse(false);
        selection.removeAllRanges();
        selection.addRange(range);
      }
    }

    function createRange(node, chars, range) {
      if (!range) {
        range = document.createRange()
        range.selectNode(node);
        range.setStart(node, 0);
      }

      if (chars.count === 0) {
        range.setEnd(node, chars.count);
      } else if (node && chars.count > 0) {
        if (node.nodeType === Node.TEXT_NODE) {
          if (node.textContent.length < chars.count) {
            chars.count -= node.textContent.length;
          } else {
            range.setEnd(node, chars.count);
            chars.count = 0;
          }
        } else {
          for (var lp = 0; lp < node.childNodes.length; lp++) {
            range = createRange(node.childNodes[lp], chars, range);

            if (chars.count === 0) {
              break;
            }
          }
        }
      }

      return range;
    }
  }

  setCurrentCursorPosition(elem, new RegExp(text).exec(elem.innerHTML).index - 1)
}

doFindStringAndMoveCaret(document.getElementById('mydiv'), 'peekabo')
<div id='mydiv' contenteditable='true'>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  Sed eget libero sit <mark>amet</mark> and **peekabo** magna sagittis sagittis quis nec risus.
  Pellentesque feugiat pharetra purus id pharetra.
</div>

这只是在 的 中找到字符串的位置innerHTML,从中div减去1,并用于setCurrentCursorPosition聚焦div并将光标移动到那里:

setCurrentCursorPosition(elem, new RegExp(text).exec(elem.innerHTML).index - 1)

函数中的其余代码已修改并取自https://stackoverflow.com/a/41034697/

如果要将光标移动到文本的开头,请使用

setCurrentCursorPosition(elem, new RegExp(text).exec(elem.innerHTML).index - text.length - 1)

反而。

function doFindStringAndMoveCaret(elem, text) {
  function setCurrentCursorPosition(element, chars) {
    element.focus()
    if (chars >= 0) {
      var selection = window.getSelection();

      range = createRange(element.parentNode, {
        count: chars
      });

      if (range) {
        range.collapse(false);
        selection.removeAllRanges();
        selection.addRange(range);
      }
    }

    function createRange(node, chars, range) {
      if (!range) {
        range = document.createRange()
        range.selectNode(node);
        range.setStart(node, 0);
      }

      if (chars.count === 0) {
        range.setEnd(node, chars.count);
      } else if (node && chars.count > 0) {
        if (node.nodeType === Node.TEXT_NODE) {
          if (node.textContent.length < chars.count) {
            chars.count -= node.textContent.length;
          } else {
            range.setEnd(node, chars.count);
            chars.count = 0;
          }
        } else {
          for (var lp = 0; lp < node.childNodes.length; lp++) {
            range = createRange(node.childNodes[lp], chars, range);

            if (chars.count === 0) {
              break;
            }
          }
        }
      }

      return range;
    }
  }

  setCurrentCursorPosition(elem, new RegExp(text).exec(elem.innerHTML).index - text.length - 1)
}

doFindStringAndMoveCaret(document.getElementById('mydiv'), 'peekabo')
<div id='mydiv' contenteditable='true'>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  Sed eget libero sit <mark>amet</mark> and **peekabo** magna sagittis sagittis quis nec risus.
  Pellentesque feugiat pharetra purus id pharetra.
</div>


推荐阅读