简体   繁体   中英

Highlight matching text

When posting users text to webpage (using Mongodb and node and js) I'm trying to highlight any of their text that matches a store name from an array of stores. The code for looping through the db and posting to page:

<% posts.forEach(function(post) { %>
    <div class="post">
         <h4 class="date">
             <span><%= post.created.toDateString() %></span>
         </h4>
         <p class="post_text"><%- post.body %></p>
    </div>
<% }); %>

I have some practice js console code I used to match words from an array but am having difficulty moving forward with putting the text back together with the highlighted word(s). 2 word store names are another issue...

var blogInput = "We went to target last night, also to publix";
var array1 = blogInput.split(" ");
var array2 = ["kroger", "lums", "marlows", "eats", "burger king", 
"home", "wendys", "publix", "donut circus", "jewelry store", 
"target"];

function getMatch(a, b) {
  var matches = [];
  for ( var i = 0; i < a.length; i++ ) {
    for ( var e = 0; e < b.length; e++ ) {          
      if ( a[i] === b[e] ) {
        var x = a[i];
        matches.push( x );
      }
    }
  }
  return matches;
}
getMatch(array1, array2); 
(2) ["target", "publix"]

Using this example I would then like to put the string sentence back together and post to page with 'target' and 'publix' text in blue. Any hints or words of wisdom would be helpful. Thanks!

You don't need two loops, just work with blogInput as a string instead of splitting it into individual words and use indexOf (or includes ) to determine if the keyword is in the string. This also solves the issues of trying to find store names with multiple words.

var blogInput = "We went to target last night, also to publix";
var array2 = ["kroger", "lums", "marlows", "eats", "burger king", 
"home", "wendys", "publix", "donut circus", "jewelry store", 
"target"];
// filter out any store names that aren't included in blogInput
var matches = array2.filter(function(store) {
   return blogInput.indexOf(store) > -1;
});

You also may want to blogInput.toLowerCase() and store.toLowerCase() to resolve casing issues.

If you are targeting new browsers with ES6 support or using a transpiler like Babel you can simplify to:

const blogInput = "We went to target last night, also to publix";
const storeNames = ["kroger", "lums", "marlows", "eats", "burger king", 
"home", "wendys", "publix", "donut circus", "jewelry store", 
"target"];
// filter out any store names that aren't included in blogInput
var matches = storeNames.filter(store => blogInput.includes(store));

You will need to surround the highlighted words in a span with an specific class that changes its color.

A function that could rebuild your post back with those spans could be similar to this one.

let blogInput = "We went to target last night, also to publix";
let blogWords = blogInput.split(" ");
let searchedWords = ["kroger", "lums", "marlows", "eats", "burger king", 
"home", "wendys", "publix", "donut circus", "jewelry store", 
"target"];

function getMatch(a, b) { ... }

let matchedWords = getMatch(blogWords, searchedWords);
let blogText = '';
blogWords.forEach(function(word) {
  if (matchedWords.indexOf(word) != -1) {
    blogText += ' <span class="highlight">' + word + '</span>';
  } else {
    blogText += ' ' + word;
  }
});
// Remove leading space
blogText = blogText.trim();

You should then use the blogText as your post text. You will also need adding a CSS rule similar to this one:

span.highlight {
  color: blue;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM