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