Ad

Replacing Words That Are Inside Html Tags

- 1 answer

My application is a document viewer/reader. There is a search function in which users input a string and it returns a list of results. In addition, the occurrences of the query are highlighted on the page to make them more visible. The issue happens when searching for terms like 'class', 'style', or other words that are also html tags.

content is just a string of html like this: "<div class='classname' style='stylename'>Words that are eligible for highlighting</div>

The highlighted word should be replaced like this:

query = 'class'

"<div class='classname' style='stylename'>Words that are eligible for highlighting are in here, including words like class and style</div>

When the application attempts to highlight these words, all the formatting on the page breaks. This is the code I am using to highlight search queries:

 searchContent(content){
  var searchQuery = SearchStore.getQuery()
  if (searchQuery) {
    var query = searchQuery.split(' ').map((q) => {
      if (q.length > 2) {
       return `\\b${q}\\b`;
     }
    }).join('|'); 
    if (query.length > 0) {
      //this is where the query is highlighted. It should not replace text inside <> tags
      content = content.replace(new RegExp(query, 'gi'), (value) => {
        return `<b style="background-color: yellow;">${value}</b>`;
      });
    }
  }
  return content;
}

is there a way to rewrite this so that it detects when it is replacing text inside an html tag and prevent the page from breaking?

Ad

Answer

In the most basic sense you could regex through tags and strings and only do replacements on the strings. Below is simple regex that assumes a tag is anything between < and >.

var content = document.getElementById('content');
var html = content.innerHTML;

html = html.replace(/<[^>]*>|[^<>]*/g, function(m){

  // this is a tag, no replace
  if (m.charAt(0) === '<') {
    return m;
  }
  
  // this is not a tag, do replacement
  return m.replace(/class/g, function(m) {
    return "<span class='match'>" + m + "</span>"
  });
  
});

content.innerHTML = html;
b.test {
  color: #009999;
  background-color: white;
}

b {
  color: white;
  background-color: #009999;
}

span.match {
  color: blue;
  background-color:white;
}
<div id='content'>
  <b class='test'>class test</b>
</div>

Ad
source: stackoverflow.com
Ad