With a contenteditable element how can I replace the selected content with my own html?
            Asked
            
        
        
            Active
            
        
            Viewed 6.2k times
        
    47
            
            
        - 
                    The second part of this question (“replace selected text with html of my own”) is not answered in he question linked as a reference for this one being a duplicate. – Brian M. Hunt Jul 15 '14 at 23:49
- 
                    I removed the already answered part to comply with the "one question per question" rule. – Brigand Jul 16 '14 at 00:16
- 
                    Related - https://stackoverflow.com/q/3997659/104380 – vsync Sep 20 '20 at 11:18
2 Answers
70
            See here for working jsFiddle: http://jsfiddle.net/dKaJ3/2/
function getSelectionHtml() {
    var html = "";
    if (typeof window.getSelection != "undefined") {
        var sel = window.getSelection();
        if (sel.rangeCount) {
            var container = document.createElement("div");
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                container.appendChild(sel.getRangeAt(i).cloneContents());
            }
            html = container.innerHTML;
        }
    } else if (typeof document.selection != "undefined") {
        if (document.selection.type == "Text") {
            html = document.selection.createRange().htmlText;
        }
    }
    alert(html);
}
Code taken from Tim Down: Return HTML from a user-selected text
 
    
    
        Community
        
- 1
- 1
 
    
    
        NakedBrunch
        
- 48,713
- 13
- 73
- 98
- 
                    BTW - Never call the function `getSelection()`, as this will override the default and cause stack recursion – tetris11 Jan 06 '13 at 17:17
- 
                    works great! thanks. how would I now replace the selected text with something else in same position as the text is? – Varun Apr 10 '13 at 02:51
- 
                    nevermind, found the answer: http://stackoverflow.com/questions/3997659/replace-selected-text-in-contenteditable-div?rq=1 – Varun Apr 10 '13 at 03:25
- 
                    Nice, But one more question please, it return the selected text from whole document, how can get only a selected div. May be a div with a distinct class? – Pritom Jun 24 '13 at 10:59
- 
                    It's not solving the problem: how would you replace the selection, if there are at least two similar strings? – k102 Mar 23 '16 at 13:27
54
            
            
        To get the selected HTML, you can use the function I wrote for this question. To replace the selection with your own HTML, you can use this function. Here's a version of the replacer function that inserts an HTML string instead of a DOM node:
function replaceSelectionWithHtml(html) {
    var range;
    if (window.getSelection && window.getSelection().getRangeAt) {
        range = window.getSelection().getRangeAt(0);
        range.deleteContents();
        var div = document.createElement("div");
        div.innerHTML = html;
        var frag = document.createDocumentFragment(), child;
        while ( (child = div.firstChild) ) {
            frag.appendChild(child);
        }
        range.insertNode(frag);
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        range.pasteHTML(html);
    }
}
replaceSelectionWithHtml("<b>REPLACEMENT HTML</b>");
- 
                    Please define `node`. I think we can just delete this line `html = (node.nodeType == 3) ? node.data : node.outerHTML;` – FirstVertex Jun 25 '14 at 14:06
- 
                    @HDog: Yes, you're right. Looks like a copy-pasted line I forgot to remove. I've deleted it now. Thanks. – Tim Down Jun 25 '14 at 19:03
- 
                    Why is 'html' both a parameter to the function and a local variable declaration? It works because of http://stackoverflow.com/a/27963351/578812 but it seems confusing at first glance. – Craig A Jul 27 '16 at 18:31
- 
                    @CraigA: It's a mistake. I suspect I copied and adapted a function that didn't have the `html` parameter. Thanks for pointing it out. – Tim Down Jul 28 '16 at 08:26
- 
                    Wonderful answer! But there's one thing I don't get, why is this valid syntax: `var frag = document.createDocumentFragment(), child;` . Why doesn't the comma raise an error? I'd be very grateful if you could explain how this statement works – flen Feb 28 '17 at 09:29
- 
                    1@flen: The `var` statement in JavaScript allows you to declare multiple variables in a single statement, separated by comma, each variable optionally having an initial value. [More info at MDN](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/var) – Tim Down Feb 28 '17 at 10:54
- 
                    @TimDown Thanks a lot! Now I got it, `child` is just a variable declaration, without any assingment. Just like `var frag = 42; var child;` – flen Mar 01 '17 at 19:55
- 
                    @TimDown, I've used this on a ContentEditable div. But it seems you can Undo/Redo anything inserted via this snippet. Is there any way to do it so Undo/Redo captures it? Thanks – Xahed Kamal Mar 27 '18 at 18:19
- 
                    @XahedKamal: I don't think so. I believe that changes made by using [`document.execCommand()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) go onto the browser undo stack but there's no command that gives you precise control over what HTML is inserted and how it's inserted. – Tim Down Mar 28 '18 at 10:06
 
     
    