Search code examples
javascripthighlighting

Highlight only keywords inside a HTML tag and not when keyword forms part of another word


It works fine as shown in the first picture

The problem appears as seen in the second picture when the keyword is misspelled

The problem is that I don't want the word to be highlighted when it forms part of another word. The problem can be seen in picture 2 where the keyword "online" is misspelled to "onlinee" and still the word "online" inside "onlinee" is highlighted. Can anyone please help me to solve this problem?

var elementId = 'colouredText';
var text = 'online';

var eee = document.getElementById(elementId).outerHTML;

var tags = [];
var tagLocations = [];
var htmlTagRegEx = /<\/?\w+((\s+\w+(\s*=\s*(?:\".*?"|'.*?'|[^'\">\s]+))?)+\s*|\s*)\/?>/gi;


//Strip the tags from the elementHtml and keep track of them

var htmlTg = eee.match(htmlTagRegEx);
console.log(htmlTg);
for (var iu = 0; iu < htmlTg.length; iu++) {
  tagLocations[tagLocations.length] = eee.search(htmlTg[iu]);
  tags[tags.length] = htmlTg[iu];

  eee = eee.replace(htmlTg[iu], '');

}
var textLocationn = eee.search(text);



if (textLocationn) {
  //Add the highlight
  var highlightHTMLStart = "<span class='red'>";
  var highlightHTMLEnd = "</span>";
  eee = eee.replace(text, highlightHTMLStart + text + highlightHTMLEnd);

  //plug back in the HTML tags
  var textEndLocationn = textLocationn + text.length;

  for (var r = (tagLocations.length - 1); r >= 0; r--) {
    var locationn = tagLocations[r];
    if (locationn > textEndLocationn) {
      locationn += highlightHTMLStart.length + highlightHTMLEnd.length;
    } else if (locationn > textLocationn) {
      locationn += highlightHTMLStart.length;
    }
    eee = eee.substring(0, locationn) + tags[r] + eee.substring(locationn);
  }

}

//Update the innerHTML of the element
document.getElementById(elementId).outerHTML = eee;
.green {
  color: green;
}

.red {
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<h1>This is a green text, and here a red text</h1>

<ul id="colouredText">
  <li class="gold-text">around 560,000 onlinee tunes, available as free sheet music or midi sound files, at this site alone</li>
  <li>traditional music from medieval &amp; renaissance times up to the present day</li>
  <li>plenty of free software (Windows, Mac, Linux, mobile, ...) to transfer abc into scores or midi sound files</li>
</ul>


Solution

  • It could be something like this:

    function search() {
      var input = document.querySelector('input');
      if (!input.value) return;
      var element = document.querySelector('ul');
      var regex = new RegExp('\\b' + input.value + '\\b(?!>)', 'g');
      var match = element.innerHTML.match(regex);
      if (!match) return;
      element.innerHTML = element.innerHTML.replace(regex, '<span class="red">' + input.value + '</span>');
      input.value = match.length + ' matches';
      input.disabled = true;
    }
    .red {
      color: red;
    }
    <input value="online">
    <button onclick="search()">Mark</button>
    
    <ul>
      <li>around 560,000 onlinee tunes, available as free sheet music or midi sound files, at this site alone</li>
      <li>online oonline online online</li>
      <li>traditional music from medieval &amp; renaissance times up to the present day</li>
      <li>plenty of free software (Windows, Mac, Linux, mobile, ...) to transfer abc into scores or midi sound files</li>
    </ul>