如何在鼠标指示的位置在textarea中插入内容

How to insert something in textarea at the location indicated by the mouse

我创建了一个将表情符号插入文本区域的脚本。问题是我使用 innerHTML 插入表情符号,这样它只会插入文本区域内容的开头或结尾。我希望能够将其插入用户指定的任何位置,这样如果您已经写下了您想要的内容,您可以 return 到文本的特定部分并简单地插入您的表情符号。有人知道如何帮助我吗?

抱歉,它不是很漂亮,但我觉得这个示例可以解释它,您可以将代码片段保存在 html 页面中,加载它并检查代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Insertion test</title>

    <style>
        .classic-button {
            width: 140px;
            height: 60px;
            font-weight: bold;
            font-size: 20px;
            border: 4px solid black;
            background-color: lightgray;
        }

        table {

            border-collapse: collapse;
        }

        td {
            border: 4px solid black;
        }

        .fs-24-b {
            font-size: 24px;
            font-weight: bold;
        }

        .fs-32-b {
            font-size: 32px;
            font-weight: bold;
        }

        .tBoxFill {
            width: 100%;
            -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
            -moz-box-sizing: border-box;    /* Firefox, other Gecko */
            box-sizing: border-box;       /* Opera/IE 8+ */
            font-size: 32px;
        }

        .td-button {
            padding: 20px;
        }

    </style>
    <script>
      let insertIn = (str1, str2, at) => {
        return str1.slice(0,at) + str2 + str1.slice(at);
      }

      function doGetCaretPosition (oField) {
        var iCaretPos = 0;

        // IE Support
        if (document.selection) {

          // Set focus on the element
          oField.focus();

          // To get cursor position, get empty selection range
          var oSel = document.selection.createRange();

          // Move selection start to 0 position
          oSel.moveStart('character', -oField.value.length);

          // The caret position is selection length
          iCaretPos = oSel.text.length;
        }

        // Firefox support
        else if (oField.selectionStart || oField.selectionStart == '0')
          iCaretPos = oField.selectionDirection=='backward' ? oField.selectionStart : oField.selectionEnd;

        // Return results
        return iCaretPos;
      }

      function getprintLastPost() {
        document.getElementById('printLastPost')
          .innerText = 'Last position : '
          + doGetCaretPosition(document.getElementById('TBtoFill'));
      }

      function insertInTBox(tBoxDOM, text) {
        let insStr = text;

        let oldCaretPos = doGetCaretPosition(tBoxDOM);
        let newCaretPos = oldCaretPos + insStr.length;

        tBoxDOM.value =  insertIn(tBoxDOM.value, insStr, oldCaretPos);

        tBoxDOM.selectionEnd = newCaretPos;
      }

      function insertStuff() {
        let toBox = document.getElementById("TBtoFill");
        let inBox = document.getElementById("TBtoInsert");

        insertInTBox(toBox, inBox.value);
      }

    </script>
</head>

<body>
    <center>
        <table>
            <tr>
                <td colspan="5">
                    <textarea class="fs-24-b" id="TBtoFill" cols="70" rows="10">

                    </textarea>
                </td>
            </tr>
            <tr>
                <td colspan="5" class="td-button">
                    <button class="classic-button" onclick="getprintLastPost()">
                        Get last pos
                    </button>
                    <span class="fs-32-b"> :
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                        </span>
                    <span id="printLastPost" class="fs-32-b">Last position : ?</span>
                </td>
            </tr>

            <tr>
                <td colspan="1"  class="td-button">
                    <button class="classic-button" onclick="insertStuff()">
                        Insert
                    </button>
                    <span class="fs-32-b"> : </span>
                </td>

                <td style="width: 80%">
                    <textarea class="tBoxFill fs-32-b" id="TBtoInsert"></textarea>
                </td>
            </tr>
        </table>
    </center>
</body>
</html>

基本上,您只需获取表情符号的 utf8 或 unicode 值,然后保留函数 doGetCaretPosition() 以使用 insertInTBox()。您根据函数将告诉您的插入符的最后位置将文本框字符串一分为二,然后连接 left-part->emoji->right 部分。