I need to programmatically add some text at the end of a text selection performed by the user. My code works fine except that I am not able to apply the class to the newly inserted element (a div). If I insert the new div to the body (document.body.appendChild(div)), the class applies correctly, so there must be something wrong in the way I add the div to the BOM after the selection. Here the text 'TEXT-TO-APPEND' is added, but not the class.
var div = document.createElement("div");
div.className = ('highlighted');
let text = document.createTextNode('TEXT-TO-APPEND');
div.appendChild(text);
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = window.getSelection().getRangeAt(0);
range.collapse(isBefore);
var frag = document.createDocumentFragment(),
node, lastNode;
while ((node = div.firstChild)) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);
}
A complete working example is this
<title>Page Title</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="">
<style>
.highlighted {
background: #ccc;
/*font-size: 18px;*/
color: red;
}
</style>
<body>
<input id="clickMe" type="button" value="clickme" onclick="insertHtmlAtSelectionEnd(' (my text) ', false);" />
<div class="">
<h1>This is a Heading</h1>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
</div>
</body>
<script>
function insertHtmlAtSelectionEnd(mytext, isBefore) {
var text = "";
var sel, range, node;
if (window.getSelection) {
var div = document.createElement("div");
div.className = ('highlighted');
let textElement = document.createTextNode(mytext);
div.appendChild(textElement);
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = window.getSelection().getRangeAt(0);
range.collapse(isBefore);
var frag = document.createDocumentFragment(), node, lastNode;
while ( (node = div.firstChild) ) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);
}
} else if (document.selection && document.selection.type != "Control") {
text = document.selection.createRange().text;
}
}
</script>
</html>