0

I have this JavaScript function that takes a string and highlight it in the html page. I'm basically trying to simulate Ctrl-F with initial value string:

Function

<script type="text/javascript"> 

function highlight(word) {
    var node = document.body;
    for (node = node.firstChild; node; node = node.nextSibling) {

        var n = node;
        var match_pos = 0;
        match_pos = n.nodeValue.indexOf(word);
        var before = n.nodeValue.substr(0, match_pos);// split into a part before the match
        var middle = n.nodeValue.substr(match_pos, word.length); // the matched word to preserve case
        var after = document.createTextNode(n.nodeValue.substr(match_pos + word.length));// and the part after the match    
        var highlight_span = document.createElement("span");// create a span in the middle
        highlight_span.style.backgroundColor = "yellow";
        highlight_span.appendChild(document.createTextNode(middle));// insert word as textNode in new span
        n.nodeValue = before; // Turn node data into before
        n.parentNode.insertBefore(after, n.nextSibling); // insert after
        n.parentNode.insertBefore(highlight_span, n.nextSibling); // insert new span
        highlights.push(highlight_span);
        highlight_span.id = "highlight_span" + highlights.length;
        node = node.nextSibling; // Advance to next node or we get stuck in a loop because we created a span (child)


    }
}

</script>

Basically, The sentence I give to the function as an argument is not highlighted. Knowing that I'm positive it exists.

This Loads the HTML page

@Html.Action("GetHtmlPage", "Upload", new { path = Model.documentPath })

Then, This Calls the funtion

@{
    var str = Model.sentence["sentence"].AsString;
    <script>highlight(@str)</script>
}

1 Answers1

0

There was a problem with your loop. Something like this will work much better.

var highlights = []
function searchElement(elem, word){
  var children = Array.prototype.slice.call(elem.childNodes);
  for(var i=0; i<children.length; i++){
    if(children[i].nodeType == Node.TEXT_NODE){
      var n = children[i];
        var match_pos = n.nodeValue.indexOf(word);
        if(match_pos == -1){
          continue;
         }
        var before = n.nodeValue.substr(0, match_pos);// split into a part before the match
        var middle = n.nodeValue.substr(match_pos, word.length); // the matched word to preserve case
        var after = document.createTextNode(n.nodeValue.substr(match_pos + word.length));// and the part after the match    
        var highlight_span = document.createElement("span");// create a span in the middle
        highlight_span.style.backgroundColor = "yellow";
        highlight_span.appendChild(document.createTextNode(middle));// insert word as textNode in new span
        n.nodeValue = before; // Turn node data into before
        n.parentNode.insertBefore(after, n.nextSibling); // insert after
        n.parentNode.insertBefore(highlight_span, n.nextSibling); // insert new span
        highlights.push(highlight_span);
        highlight_span.id = "highlight_span" + highlights.length;
    }else if(children[i].childNodes.length){
      searchElement(children[i], word);
    }
  }
}
function highlight(word) {
    searchElement(document.body, word)
}

highlight("Even more test");
test
<div>
  More test
  
  <span>Even more test</span>
</div>
JstnPwll
  • 8,585
  • 2
  • 33
  • 56
  • What If I want to highlight a specific sentence in the document at the load time. without asking the user what to highlight? – Nasri Yatim Apr 26 '17 at 22:51
  • For example I know that the html document will contain "Specific String", how can I highlight it instantly without clicking the button? – Nasri Yatim Apr 26 '17 at 22:52
  • It's just a function, you can call the function from wherever. It doesn't have to be on a button click. Check out the edited code snippet. – JstnPwll Apr 27 '17 at 01:41