如何获得正确的插入位置

时间:2016-06-24 10:50:12

标签: javascript jquery

我正在制作一个基于可信的输入,我想添加表情符号支持

我有contenteditable div,里面只有文字和IMG_TAG表情符号。在模糊,我想保存插入位置。当我点击打开表情符号框以集中满足时,将插入符号放在原处。模拟web.whatsapp.com行为的东西

我找到了这段代码

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;
}

但它没有给我正确的位置。

"你好IMG_TAG john"。如果光标就在IMG_TAG之前 - >位置是6,这是正确的,但如果它刚好在IMG_TAG仍然是6之后。 此外,我没有找到一个好的" setCaretPosition"功能对我有用。

我现在已经找了两个小时。有人得到了一个很好的答案吗?

1 个答案:

答案 0 :(得分:0)

在演示中,我们使用了Selection和Range API来设置和获得插入符号的位置。由于OP需要找到插入符号的位置,我们将专注于getCaret()函数:

    var btn2 = document.getElementById('btn2');

    btn2.addEventListener('click', getCaret, false);

    function getCaret() {
      var sel = window.getSelection();
      var end = sel.focusOffset;
      var out1 = document.getElementById('out1');
      out1.textContent = end;
    }
  • 该函数引用Selection对象
  • 然后存储Selection对象的属性focusOffset
  • focusOffset将给出一个整数,表示它之间的字符数(focusNode)和Selection(anchorNode)的开头。如果Selection包含一个元素,那么它也将元素的childNodes包含在计数中。

测试getCaret()功能时,只需选择一些文字,然后点击获取焦点按钮,结果会显示在标有Caret Position:

的区域旁边

<!DOCTYPE html>
<html>

<head>
  <meta charset='utf-8'>
  <style>
    fieldset {
      margin: 20px auto;
    }
    input {
      width: 5ex;
      text-align: center;
      padding: 1px 3px;
    }
  </style>
</head>

<body>

  <div id="editor1" contenteditable="true">
    <br/>123456789abcdefghijklmnopqrstuvwxyz
    <br/>12 45678 abcd fg ijk mnopqrst vwxyz
    <br/>123 5 789a cde ghijklm o qrst v xyz
    <br/>12345 789abcd fg ijklmnopq s u wxyz
    <br/>123 567 9abc efg ijklm op rst vwxy
    <br/>1 34 6789a cdef hij lm opq stuvwxyz
    <br/>1 3456 89a cd fghij l no qrst vwx z
    <br/>12 4 6789 bcd fgh j lmno q stuv xy
  </div>
  <fieldset>

    <input type="button" class="fontStyle" onclick="document.execCommand('italic',false,null);" value="I" title="Italicize Highlighted Text">
    <input type="button" class="fontStyle" onclick="document.execCommand('bold',false,null);" value="B" title="Bold Highlighted Text">
    <input id="row" name="row" placeholder="Row#" />
    <input id="col" name="col" placeholder="Col#" />
    <button id="btn1">Set Focus</button>
    <button id="btn2">Get Focus</button>
    <label for='out1'>Caret Position:</label>
    <output id="out1"></output>
  </fieldset>
  <p>Each row has a number of non-repeated string of alphanumeric characters:</p>
  <pre><code>123456789abcdefghijklmnopqrstuvwxyz</code></pre>
  <p>Maximum of 35 characters. Every row except the first row has some missing characters and in their place is a whitespace.
  </p>
  <script>
    function setCaret(x, y) {

      var ele = document.getElementById("editor1");
      var rng = document.createRange();
      var sel = window.getSelection();
      var row = parseInt(x, 10) * 2;
      var col = parseInt(y, 10);
      rng.setStart(ele.childNodes[row], col);
      rng.collapse(true);
      sel.removeAllRanges();
      sel.addRange(rng);
      ele.focus();
    }

    function getCaret() {
      var sel = window.getSelection();
      var end = sel.focusOffset;
      var out1 = document.getElementById('out1');
      out1.textContent = end;
    }


    var btn2 = document.getElementById('btn2');
    var btn1 = document.getElementById('btn1');

    btn1.addEventListener('click', function(event) {
      var rowSet = document.getElementById('row').value;
      var colSet = document.getElementById('col').value;
      setCaret(rowSet, colSet);
    }, true);

    btn2.addEventListener('click', getCaret, false);
  </script>
</body>

</html>

在试图记住setCaret()功能如何运作之后,想出来了。