1

I'm using the following js to highlight the content of searched string in html, but the problem is that this also affects the url string.

var a = new RegExp(keywords, "igm");
container.innerHTML = container.innerHTML.replace(a, "<span style='background:#FF0;'>" + keywords + "</span>");

If the keyword is in the url, then the url will be relaced with xxxx.com/<span style='background:#FF0;'>product</span> which is wrong.

So is there any way to filter out the words that not contained in url? Not sure if there is a RegExp could do this. Thanks in advance.

JerryCai
  • 1,663
  • 4
  • 21
  • 36
  • Well, you don't want to replace innerHTML as string since that also breaks for example current eventListeners on elements in the container. You'd need to loop over DOM nodes and perform replace actions explicitly on textNodes using a conditional check on parentNode. – BGerrissen May 03 '14 at 06:07
  • possible duplicate of [How to highlight text using javascript](http://stackoverflow.com/questions/8644428/how-to-highlight-text-using-javascript) – Ja͢ck May 05 '14 at 02:01
  • @Jack, it appears your link is about simple replacement rather than avoiding HTML code. @JerryCai wants to operate on just the rendered text without affecting the code, e.g. `'stuff fox'.safe_replace(/f/igm,"b")` would become `stuff box` (or stubb? that part is unclear to me). – Adam Katz May 06 '14 at 16:20

1 Answers1

1

Here is a block of code that does what you ask:

// prepare the replacement as a function
function do_replacement(node) {
  var a = new RegExp(keywords, "igm");
  node.innerHTML = node.innerHTML.replace(a,
    "<span style='background:#FF0;'>" + keywords + "</span>");
}

// back up the links
var link_backups = new Array();
var link_refs = new Array();
var container_links = container.getElementsByTagName("a");
for (var i = 0; i < container_links.length; i++) {
  var copy = container_links[i].cloneNode(true);
  // the link target (href) is not contained in the link's innerHTML
  // remove this line if you don't want to replace the link's TEXT
  do_replacement(copy);
  link_backups.push(copy);
  link_refs[i] = container_links[i];
}

do_replacement(container);

// restore the backed up links
// (this uses link_refs[] because container_links[] could have changed)
for (var i = 0; i < link_refs.length; i++) {
  container.replaceChild(link_backups[i], link_refs[i]);
}

This will (probably) fail if your keywords matches the tag name (<a>) of the links, e.g. when keywords = "a".

However, I'm sure you'll merely run into another instance of HTML code that you don't actually want to replace. JS doesn't really have the best of ways to manipulate just the DOM's text. For example, changing Node.textContent will kill all of the node's HTML content.

Adam Katz
  • 14,455
  • 5
  • 68
  • 83