'Remove any span with specific class in selected text
I'm trying to remove any tag with the class "high" in any selected text of a contentEditable div.
No matters if the span node is fully selected or partially selected! Like the example:
In this example above, note that the span with "adipiscing elit" text is just partially selected! But when user clicks one button "remove highlight", I'm trying to make this <span> class vanish! But keep the text (remove only the tag). And if the selection has one or more spans with the class "high", all should be removed!
I'm stuck because I don't know how to get the index of the node, for example. I was able to identify if there is a span with that class in the selection. But how to do this removal?
Here is what I have:
<div contentEditable='true' spellcheck='false'>
Lorem ipsum <a href='eer.htm'>dolor sit amet</a>, consectetur <span class='high'>adipiscing elit</span>. Ut lacinia eros ut orci pellentesque vulputate. Mauris sodales odio.
</div>
<br />
<button id='remove'>Remove Highlight</button>
JS:
remove.onclick = e => remove();
function nextNode(node) {
if (node.hasChildNodes()) {
return node.firstChild;
} else {
while (node && !node.nextSibling) {
node = node.parentNode;
}
if (!node) {
return null;
}
return node.nextSibling;
}
}
function getRangeSelectedNodes(range) {
var node = range.startContainer;
var endNode = range.endContainer;
if (node == endNode) {
return [node];
}
var rangeNodes = [];
while (node && node != endNode) {
rangeNodes.push( node = nextNode(node) );
}
node = range.startContainer;
while (node && node != range.commonAncestorContainer) {
rangeNodes.unshift(node);
node = node.parentNode;
}
return rangeNodes;
}
function getSelectedNodes() {
if (window.getSelection) {
var sel = window.getSelection();
if (!sel.isCollapsed) {
return getRangeSelectedNodes(sel.getRangeAt(0));
}
}
return [];
}
function remove() {
var nds = getSelectedNodes();
var i;
for(i=0; i<=nds.length;i++) {
if(nds[i] instanceof HTMLSpanElement) {
if(nds[i].classList == 'high') {
var spanText = nds[i].textContent;
}
}
}
}
remove.onclick = e => remove();
function nextNode(node) {
if (node.hasChildNodes()) {
return node.firstChild;
} else {
while (node && !node.nextSibling) {
node = node.parentNode;
}
if (!node) {
return null;
}
return node.nextSibling;
}
}
function getRangeSelectedNodes(range) {
var node = range.startContainer;
var endNode = range.endContainer;
if (node == endNode) {
return [node];
}
var rangeNodes = [];
while (node && node != endNode) {
rangeNodes.push( node = nextNode(node) );
}
node = range.startContainer;
while (node && node != range.commonAncestorContainer) {
rangeNodes.unshift(node);
node = node.parentNode;
}
return rangeNodes;
}
function getSelectedNodes() {
if (window.getSelection) {
var sel = window.getSelection();
if (!sel.isCollapsed) {
return getRangeSelectedNodes(sel.getRangeAt(0));
}
}
return [];
}
function remove() {
var nds = getSelectedNodes();
var i;
for(i=0; i<=nds.length;i++) {
if(nds[i] instanceof HTMLSpanElement) {
if(nds[i].classList == 'high') {
var spanText = nds[i].textContent;
}
}
}
}
.high { background:yellow; }
<div contentEditable='true' spellcheck='false'>
Lorem ipsum <a href='eer.htm'>dolor sit amet</a>, consectetur <span class='high'>adipiscing elit</span>. Ut lacinia eros ut orci pellentesque vulputate. Mauris sodales odio.
</div>
<br />
<button id='remove'>Remove Highlight</button>
Solution 1:[1]
You should use .classList.contains and .classList.remove. See Element.classList.
document.getElementById("remove").onclick = e => remove();
function nextNode(node) {
if (node.hasChildNodes()) {
return node.firstChild;
} else {
while (node && !node.nextSibling) {
node = node.parentNode;
}
if (!node) {
return null;
}
return node.nextSibling;
}
}
function getRangeSelectedNodes(range) {
var node = range.startContainer;
var endNode = range.endContainer;
if (node == endNode) {
return [node];
}
var rangeNodes = [];
while (node && node != endNode) {
rangeNodes.push( node = nextNode(node) );
}
node = range.startContainer;
while (node && node != range.commonAncestorContainer) {
rangeNodes.unshift(node);
node = node.parentNode;
}
return rangeNodes;
}
function getSelectedNodes() {
if (window.getSelection) {
var sel = window.getSelection();
if (!sel.isCollapsed) {
return getRangeSelectedNodes(sel.getRangeAt(0));
}
}
return [];
}
function remove() {
var nds = getSelectedNodes();
var i;
for(i=0; i<=nds.length;i++) {
if(nds[i] instanceof HTMLSpanElement) {
if(nds[i].classList.contains('high')) {
nds[i].classList.remove('high');
var spanText = nds[i].textContent;
}
}
}
}
.high { background:yellow; }
<div contentEditable='true' spellcheck='false'>
Lorem ipsum <a href='eer.htm'>dolor sit amet</a>, consectetur <span class='high'>adipiscing elit</span>. Ut lacinia eros ut orci pellentesque vulputate. Mauris sodales odio.
</div>
<br />
<button id='remove'>Remove Highlight</button>
Solution 2:[2]
You code is long but, your main issue is this right. You can't remove the highlighted text.
Your Remove Highlight button cant execute your remove() function. you should at least properly target it first. like below.
document.querySelector('#remove').onclick = e => remove();
and add
document.querySelector('.high').remove();
to remove the text with hightlight
document.querySelector('#remove').onclick = e => remove();
function remove() {
var nds = getSelectedNodes();
var i;
for(i=0; i<=nds.length;i++) {
if(nds[i] instanceof HTMLSpanElement) {
if(nds[i].classList == 'high') {
var spanText = nds[i].textContent;
}
}
}
document.querySelector('.high').remove();
}
function nextNode(node) {
if (node.hasChildNodes()) {
return node.firstChild;
} else {
while (node && !node.nextSibling) {
node = node.parentNode;
}
if (!node) {
return null;
}
return node.nextSibling;
}
}
function getRangeSelectedNodes(range) {
var node = range.startContainer;
var endNode = range.endContainer;
if (node == endNode) {
return [node];
}
var rangeNodes = [];
while (node && node != endNode) {
rangeNodes.push( node = nextNode(node) );
}
node = range.startContainer;
while (node && node != range.commonAncestorContainer) {
rangeNodes.unshift(node);
node = node.parentNode;
}
return rangeNodes;
}
function getSelectedNodes() {
if (window.getSelection) {
var sel = window.getSelection();
if (!sel.isCollapsed) {
return getRangeSelectedNodes(sel.getRangeAt(0));
}
}
return [];
}
document.querySelector('#remove').onclick = e => remove();
function remove() {
var nds = getSelectedNodes();
var i;
for(i=0; i<=nds.length;i++) {
if(nds[i] instanceof HTMLSpanElement) {
if(nds[i].classList == 'high') {
var spanText = nds[i].textContent;
}
}
}
document.querySelector('.high').remove();
}
.high { background:yellow; }
<div contentEditable='true' spellcheck='false'>
Lorem ipsum <a href='eer.htm'>dolor sit amet</a>, consectetur <span class='high'>adipiscing elit</span>. Ut lacinia eros ut orci pellentesque vulputate. Mauris sodales odio.
</div>
<br />
<button id='remove'>Remove Highlight</button>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Unmitigated |
| Solution 2 | halfer |

