In div text area, insert at cursor position

  • Requirement background: use the content editable = "true" of div to insert some labels containing text in non pure text format. In vue project, I use v-html to render. v-model cannot meet our requirements
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Editable DIV(compatible IE8)</title>
    <style type="text/css">
    #content {
        width: 500px;
        height: 200px;
        border: 1px solid #CCC;
    }
    </style>
</head>

<body>
    <button id="insert" unselectable="on" onmousedown="return false">Smiling face</button>
    <div id="content" contenteditable="true"></div>
    <script type="text/javascript">
        // Insert html code at the cursor position, and append to the end if the dom does not get the focus
        window.onload= function(){
            function insertAtCursor(jsDom, html) {
            if (jsDom != document.activeElement) { // If the dom does not get the focus, append
                jsDom.innerHTML = jsDom.innerHTML + html;
                return;
            }
            var sel, range;
            if (window.getSelection) {
                // IE9 or non IE browser
                debugger
                sel = window.getSelection();
                if (sel.getRangeAt && sel.rangeCount) {
                    range = sel.getRangeAt(0);
                    range.deleteContents();
                    // Range.createContextualFragment() would be useful here but is
                    // non-standard and not supported in all browsers (IE9, for one)
                    var el = document.createElement("div");
                    el.innerHTML = html;
                    var frag = document.createDocumentFragment(),
                        node, lastNode;
                    while ((node = el.firstChild)) {
                        lastNode = frag.appendChild(node);
                    }
                    range.insertNode(frag);
                    // Preserve the selection
                    if (lastNode) {
                        range = range.cloneRange();
                        range.setStartAfter(lastNode);
                        range.collapse(true);
                        sel.removeAllRanges();
                        sel.addRange(range);
                    }
                }
            } else if (document.selection && document.selection.type != "Control") {
                // IE < 9
                document.selection.createRange().pasteHTML(html);
            }
        }

        //  Click Insert
        document.getElementById('insert').onclick = function() {
            var html = ':)';
            insertAtCursor(document.getElementById('content'), html);
        };
    }

    </script>
</body>

</html>
demo effect

js api

  • document.activeElement this attribute is part of HTML5. It returns the currently focused element or "body" if it does not exist.
  • Selection object selection is to operate on the currently activated selection area (i.e. highlighted text). In non IE browser (Firefox, Safari, Chrome, Opera), you can use window.getSelection() to get the selection object. This article describes the standard selection operation method. Most of the content comes from https://developer.mozilla.org/en/DOM/Selection
Method
  • getRangeAt(index) gets a range object from the current selection object.
  • addRange(range) adds a range to a selection, so there can be multiple ranges in a selection. Note that Chrome doesn't allow multiple ranges at the same time, and it's handled in a slightly different way than Firefox.
  • Removeange (range) removes the range object from the current selection and returns the value undefined. Chrome has not changed the function at present. Even in Firefox, if you use the range created by yourself (document.createRange()) as a parameter, an error will be reported. If you get it with oSelction.getRangeAt(), no error will be reported.
  • removeAllRanges() removes all range objects in the selection. After execution, the anchorNode and focusNode are set to null, and there is no selected content.

Tags: IE Firefox Vue Javascript

Posted on Mon, 06 Jan 2020 04:31:56 -0800 by prometheuzz