I have seen many posts pertaining to highlighting text in a DIV using javascript, but none do quite what I’m looking for.
What I need to do is highlight the text within a specific DIV, character by character as the user enters the search term. Conversely, as the user backspaces or deletes characters, I need to “de-highlight” the text of the same DIV.
I imagine this has already been done somewhere by someone, but I have not yet found a post here or from Google that behaves exactly as I need.
Any feedback is appreciated.
this code executes as user types characters into an input field. The problem with it is that in some instances, it inserts the string ” ” into the table as I type and I don’t know why, so I’m searching for a different solution.
Thanks for your feedback!
function filterTable(Stxt, table) { dehighlight(document.getElementById(table)); if (Stxt.value.length > 0) highlight(Stxt.value.toLowerCase(), document.getElementById(table)); } function dehighlight(container) { for (var i = 0; i < container.childNodes.length; i++) { var node = container.childNodes[i]; if (node.attributes && node.attributes['class'] && node.attributes['class'].value == 'highlighted') { node.parentNode.parentNode.replaceChild( document.createTextNode(node.parentNode.innerHTML.replace(/<[^>]+>/g, "")),node.parentNode); return; } else if (node.nodeType != 3) { dehighlight(node); } } } function highlight(Stxt, container) { for (var i = 0; i < container.childNodes.length; i++) { var node = container.childNodes[i]; if (node.nodeType == 3) { var data = node.data; var data_low = data.toLowerCase(); if (data_low.indexOf(Stxt) >= 0) { var new_node = document.createElement('span'); node.parentNode.replaceChild(new_node, node); var result; while ((result = data_low.indexOf(Stxt)) != -1) { new_node.appendChild(document.createTextNode(data.substr(0, result))); new_node.appendChild(create_node( document.createTextNode(data.substr(result, Stxt.length)))); data = data.substr(result + Stxt.length); data_low = data_low.substr(result + Stxt.length); } new_node.appendChild(document.createTextNode(data)); } } else { highlight(Stxt, node); } } } function create_node(child) { var node = document.createElement('span'); node.setAttribute('class', 'highlighted'); node.attributes['class'].value = 'highlighted'; node.appendChild(child); return node; }
Advertisement
Answer
This can be easily done with a regular expression to change the div’s content. Here’s a simple implementation :
var s = document.getElementById('s'); // your input var div = document.getElementById('a'); // the div to change var t = a.textContent || a.innerText; s.onkeyup = function(){ div.innerHTML = this.value ? t.replace(new RegExp('('+this.value+')','ig'), '<span class=highlight>$1</span>') : t; };
Demonstration (click “Run with JS”)
EDIT :
This more sophisticated version works even if you have tables and stuff :
var s = document.getElementById('s'); var div = document.getElementById('a'); function changeNode(n, r, f) { f=n.childNodes; for(c in f) changeNode(f[c], r); if (n.data) { f = document.createElement('span'); f.innerHTML = n.data.replace(r, '<span class=found>$1</span>'); n.parentNode.insertBefore(f, n); n.parentNode.removeChild(n); } } s.onkeyup = function(){ var spans = document.getElementsByClassName('found'); while (spans.length) { var p = spans[0].parentNode; p.innerHTML = p.textContent || p.innerText; } if (this.value) changeNode( div, new RegExp('('+this.value+')','gi') ); };
Demonstration (click “Run with JS”)