Search code examples
javascripthtmlcsshtml-parsinghighlighting

Highlighted a specific string within a div


I have a simple HTML page in jsFiddle that should open .txt log files:

var openFile = function(event) {
  var input = event.target;
  var reader = new FileReader();
  reader.onload = function() {
    var text = reader.result;
    var node = document.getElementById('output');

    node.innerText = text;
  };
  reader.readAsText(input.files[0]);
};

var status = '<h2><br/><center>I want to change the colour of the >>> @ <<< symbol</center></h2>',
  newStatus = status.replace(/@/g, '<span class="atSign">@</span>');
console.log(newStatus);

document.getElementById('output').innerHTML = newStatus;
.atSign {
  color: #f90;
}
<center>
  <h1>.TXT Log Parser</h1>
</center>

<center>
  <h2><input type='file' accept='text/plain' onchange='openFile(event)'></h2>
</center>
<br/>
<div id='output'>...</div>

Link to JSFiddle Project:

https://jsfiddle.net/baivong/60py489j/

As you can see in the example, I can read the output as text, and I can even do a little bit of JS and CSS to change the colour of a specific character in specific string.

Since the content of the .txt log is not in my html or js, how do you suggest I highlight content in the #output ?


Solution

  • In the onload function, you need to replace the text with the formatted HTML.

    Take care not to insert the uploaded text as string-replaced HTML alone; that will allow arbitrary scripts (and other things) to be executed. Instead, split the text by @s, and append a styled span after each segment (except the last).

    var openFile = function(event) {
      var input = event.target;
      var reader = new FileReader();
      reader.onload = function() {
        var text = reader.result;
        var output = document.getElementById('output');
        
        const lines = text.split('\n');
        lines.forEach((line) => {
          const div = output.appendChild(document.createElement('div'));
          const textSplitAroundAt = line.split('@');
          textSplitAroundAt.forEach((text, i) => {
            div.appendChild(document.createTextNode(text));
            if (i === textSplitAroundAt.length - 1) return;
            const span = div.appendChild(document.createElement('span'));
            span.textContent = '@';
            span.className = 'atSign';
          });
        });
      };
      reader.readAsText(input.files[0]);
    };
    .atSign {
      color: #f90;
    }
    <center>
      <h1>.TXT Log Parser</h1>
    </center>
    
    <center>
      <h2><input type='file' accept='text/plain' onchange='openFile(event)'></h2>
    </center>
    <br/>
    <div id='output'>...</div>