Is there a way to insert text similar to bbcode before and after the selected text in a contenteditable div? I've seen many answers for textarea, but the code does not work with a contenteditable div. IE support is not needed.
Asked
Active
Viewed 5,307 times
2 Answers
16
The approach I'd suggest is:
- Obtain a range from the selection
- Insert a text node at the end of the range
- Insert another text node at the start of the range
- Reselect the original text
The following demo will work in all major browsers except IE <= 8.
Demo: http://jsfiddle.net/8WEru/
Code:
function surroundSelection(textBefore, textAfter) {
if (window.getSelection) {
var sel = window.getSelection();
if (sel.rangeCount > 0) {
var range = sel.getRangeAt(0);
var startNode = range.startContainer, startOffset = range.startOffset;
var startTextNode = document.createTextNode(textBefore);
var endTextNode = document.createTextNode(textAfter);
var boundaryRange = range.cloneRange();
boundaryRange.collapse(false);
boundaryRange.insertNode(endTextNode);
boundaryRange.setStart(startNode, startOffset);
boundaryRange.collapse(true);
boundaryRange.insertNode(startTextNode);
// Reselect the original text
range.setStartAfter(startTextNode);
range.setEndBefore(endTextNode);
sel.removeAllRanges();
sel.addRange(range);
}
}
}

Tim Down
- 318,141
- 75
- 454
- 536
-
Thank you! Is there a way to use an html element if I need to, to show boldness instead of the [b] tag? Like a rich text editor? – Flaxbeard Jul 06 '13 at 21:04
-
@Flaxbeard: If boldness is more important than controlling precise mark-up, I'd use `document.execCommand("bold", false, null)`. Otherwise, you could adapt [this answer](http://stackoverflow.com/a/6691294/96100). – Tim Down Jul 06 '13 at 23:02
-
I'd rather not use execcommand as it's uncontrollable cross-browser and only works for some tags. Do I just use createElement("strong"); and set the innerhtml to the selected text? Also, how would I add a style/class/id to this element? – Flaxbeard Jul 06 '13 at 23:24
-
1I started working on this project again and I'm wondering how I can insert an html element instead of text without using execcommand. – Flaxbeard Aug 30 '13 at 14:51
-
@Flaxbeard: Just create elements rather text nodes for `startTextNode` and `endTextNode`. – Tim Down Nov 28 '13 at 10:30
-
is there not a more concise/easier way to do this? – oldboy Nov 09 '17 at 00:41
-
1@Anthony: No. There are shortcuts you could take if, say, you knew the selection was completely contained within a single text node but for the general case there is no specific native API for this particular task so you have to use what there is. – Tim Down Nov 09 '17 at 10:12
-
How would one get this to work on highlighted text *inside* a textarea element? – ptrcao Dec 16 '22 at 19:56
3
If I understand from your comments the new goal, you have a selection and want to surround it by an element. Then the surroundContents method of range should work:
var selection = window.getSelection();
var range = selection.getRangeAt(0);
var strong = document.createElement('strong');
range.surroundContents(strong);

Leos Ondra
- 1,575
- 3
- 11
- 16