javascript - Replace text inside an element with text containing html, without removing html already present -
i trying create text search function having hard time getting work when there html inside element. here simple html demonstrate problem.
<b> <input type="checkbox" value="" /> need replaced </b>
and here @ javascript. works great assuming there no html inside.
$("*", search_container).each(function() { var replacetxt = $(this).text().replace(new regexp("(" + search_term + ")", 'i'), '<span style="color: #0095da;" class="textsearchfound">$1</span>'); $(this).text().replacewith(replacetxt); });
as user typing need replace text span. content should following he/she types.
<b> <input type="checkbox" value="" /> <span style="color: #0095da" class="textsearchfound">i need</span> replaced </b>
update
after looking on question voted duplicate came this. although may close, inserts html dom text not want. please vote reopen this.
$("*", search_container).each(function() { var node = $(this).get(0); var childs = node.childnodes; for(var inc = 0; inc < childs.length; inc++) { //text node if(childs[inc].nodetype == 3){ if(childs[inc].textcontent) { childs[inc].textcontent = childs[inc].textcontent.replace(new regexp("(" + search_term + ")", 'i'), '<span style="color: #0095da;" class="textsearchfound">$1</span>'); } //ie else { childs[inc].nodevalue = childs[inc].nodevalue.replace(new regexp("(" + search_term + ")", 'i'), '<span style="color: #0095da;" class="textsearchfound">$1</span>'); } } } });
it's not pretty, best way loop through every node on page recursively. when come across text node, check if contains search string. if find it, delete original text node , replace text node of text before match, new element highlighted match, , text node of what's after match.
here's example function:
var highlightsometext = function(needle, node){ node = node || document.body; // initialize first node, start @ body if(node.nodename == 'script') return; // don't mess script tags if(node.nodetype == 3){ // if node type text, search our needle var parts = node.nodevalue.split(needle); // split text our needle if(parts.length > 1){ // if found our needle var parent = node.parentnode for(var = 0, l = parts.length; < l;){ var newtext = document.createtextnode(parts[i++]); // create new text node, increment parent.insertbefore(newtext, node); if(i != l){ // if we're not on last part, insert new span element our highlighted text var newspan = document.createelement('span'); newspan.classname = 'textsearchfound'; newspan.style.color = '#0095da'; newspan.innerhtml = needle; parent.insertbefore(newspan, node); } } parent.removechild(node); // delete original text node } } for(var = node.childnodes.length; i--;) // loop through child nodes highlightsometext(needle, node.childnodes[i]); }; highlightsometext('i need');
and demo on jsfiddle: http://jsfiddle.net/8mpqe/
edit: here updated method uses regexp case-insensitive: http://jsfiddle.net/rpurg/
updated lines:
var parts = node.nodevalue.split(new regexp('(' + needle + ')','i'));
using regular expression wrapped in capturing group ()
results of capture spliced array of parts.
newspan.innerhtml = parts[i++];
the text new span element next part in our array.
edit 2: since function being called on every keyup event of text field, asker wanted remove highlighted span tags before each run. this, necessary unwrap each highlighted element, call normalize
on parent node merge adjacent text nodes together. here's jquery example:
$('.textsearchfound').each(function(i, el){ $(el).contents().unwrap(). parent()[0].normalize(); });
and here's completed working demo: http://jsfiddle.net/xrl3f/
Comments
Post a Comment