Face Code Face Code - 3 months ago 11
jQuery Question

How to use replace statements with JQuery but exclude one class?

I have a search engine. When you are directed to the next page, the keywords in the search bar are highlighted on the page. However, there is a particular link that I don't want highlighted. The highlighter is messing up the links url, so I get a link like:

<a href='page.php?url=ha<mark>ppy</mark>'</a> ha<mark>ppy</mark></a>


This is the code I'm using:

function term(word) {
var src_str = $("#page").html();
var term = word;
term = term.replace(/(\s+)/,"(<[^>]+>)*$1(<[^>]+>)*");
var pattern = new RegExp("("+term+")", "gi");

src_str = src_str.replace(pattern, "<mark>$1</mark>");
src_str = src_str.replace(/(<mark>[^<>]*)((<[^>]+>)+)([^<>]*<\/mark>)/,"$1</mark>$2<mark>$4");

$("#page").html(src_str);
}


I want the code to have the same replace functionality, but not replace
.topic_link


EDIT

The problem is not only with
.topic_link
. The code affects all the html of the page. So, if I searched "div", all the outside HTML code would be affected. Is there a way to only affect the text of the document and not the HTML?

Answer

It seems you'll have to traverse through children and check their node types. Since every child can have other children, recursion must be applied:

function changeText(word,element) {   
  $.each(element.contents(),function(){
    if(this.nodeType == 1)
      changeText(word,$(this));
    else if(this.nodeType == 3)
    {
      $(this).replaceWith(term(word,$(this).text()));
    }
  });

}

function term(word,src_str) {

  var term = word;
  term = term.replace(/(\s+)/,"(<[^>]+>)*$1(<[^>]+>)*");
  var pattern = new RegExp("("+term+")", "gi");

  src_str = src_str.replace(pattern, "<mark>$1</mark>");
  src_str = src_str.replace(/(<mark>[^<>]*)((<[^>]+>)+)([^<>]*<\/mark>)/,"$1</mark>$2<mark>$4");

  return src_str;
}

Now call:

changeText("YourWord",$("#page"));

This has been tested on small amount od data, so I don't know if it'll be efficient enough.