Insert an HTML element in a contentEditable element

前端 未结 2 892
我在风中等你
我在风中等你 2021-02-03 14:57

I have a contentEditable div where I want to insert HTML tags (a simple span element).

Is there a cross browser solution that allows me to insert those tags over my div

相关标签:
2条回答
  • 2021-02-03 15:18

    Here is a kickstart

    // get the selection range (or cursor     position)
    var range = window.getSelection().getRangeAt(0); 
    // create a span
    var newElement = document.createElement('span');
    newElement.id = 'myId';
    newElement.innerHTML = 'Hello World!';
    
    // if the range is in #myDiv ;)
    if(range.startContainer.parentNode.id==='myDiv') {
       // delete whatever is on the range
       range.deleteContents();
       // place your span
       range.insertNode(newElement);
    }
    

    I don't have IE but works fine on firefox, chrome and safari. Maybe you want to play with range.startContainer to proceed only if the selection is made on the contentEditable div.

    EDIT: According to quirksmode range intro you have to change the window.getSelection() part to be IE compatible.

    var userSelection;
    if (window.getSelection) {
        userSelection = window.getSelection();
    }
    else if (document.selection) { // should come last; Opera!
        userSelection = document.selection.createRange();
    }
    
    0 讨论(0)
  • 2021-02-03 15:33

    The following will do this in all major browsers (including IE 6). It will also handle cases where the end of the selection is outside your <div> and cases where the selection is contained within a child (or more deeply nested) element inside the <div>.

    2019 addendum: The second branch of insertNodeOverSelection is for IE <= 8 only and could be removed now.

    function isOrContainsNode(ancestor, descendant) {
        var node = descendant;
        while (node) {
            if (node === ancestor) return true;
            node = node.parentNode;
        }
        return false;
    }
    
    function insertNodeOverSelection(node, containerNode) {
        var sel, range, html;
        if (window.getSelection) {
            sel = window.getSelection();
            if (sel.getRangeAt && sel.rangeCount) {
                range = sel.getRangeAt(0);
                if (isOrContainsNode(containerNode, range.commonAncestorContainer)) {
                    range.deleteContents();
                    range.insertNode(node);
                } else {
                    containerNode.appendChild(node);
                }
            }
        } else if (document.selection && document.selection.createRange) {
            range = document.selection.createRange();
            if (isOrContainsNode(containerNode, range.parentElement())) {
                html = (node.nodeType == 3) ? node.data : node.outerHTML;
                range.pasteHTML(html);
            } else {
                containerNode.appendChild(node);
            }
        }
    }
    <input type="button" onmousedown="insertNodeOverSelection(document.createTextNode('[NODE]'), document.getElementById('test'));" value="insert">
    
    <div contenteditable="true">
        <div id="test" style="background-color: lightgoldenrodyellow">
            This is the editable element where the insertion will happen. Select something or place the cursor in here, then hit the button above
        </div>
        <div>
            No insertion will happen here
        </div>
    </div>

    0 讨论(0)
提交回复
热议问题