1

How can I use an array for this instance? I'd like to change both bar and foo's font color.

var colorRed = ['bar', 'foo'];
$(document).ready(function () {
    $(".msg:contains('"+colorRed+"')").each(function () {
        var regex = new RegExp(colorRed,'gi');
        $(this).html($(this).text().replace(regex, "<span class='red'>"+colorRed+"</span>"));
    });
});
.red {
    color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="msg">select bar and foo in this sentence</div>

1
  • 1
    PS: :contains is case sensitive, so it makes no sense to use it, specially if afterwards you use the RegExp's i (insensitive) flag. Commented Jul 7, 2020 at 22:30

3 Answers 3

1

Use .join("|") to create a Matching Group with optional | values.

Basically it will create a Regex like /(bar|foo)/ and extract the matching value using $& placeholder:

const words = ["bar", "foo"];
const regex = new RegExp(`(${words.join("|")})`, 'gi');

jQuery(function($) { // Better DOM ready. And $ alias in scope

  $(".msg").html(function() {
    if (regex.test(this.textContent))
      return this.textContent.replace(regex, "<span class='red'>$&</span>");
  });

});
.red { color: red; }
<div class="msg">select bar and foo in this FOO sentence</div>
<div class="msg">Foo enters <b>the bar</b> (HTML is lost)</div>
<div class="msg"><b>Nothing to edit here</b> (HTML is preserved)</div>

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

Also, no need to use .each() when you need only to update the innerHTML - use directly the jQuery's .html() Method as above.

PS1: :contains is case sensitive, so it makes no sense to use it, specially if afterwards you use the RegExp's i (insensitive) flag.

PS2: if you don't want to highlight bar in bartender use the \b word boundary:

const regex = new RegExp(`\\b(${words.join("|")})\\b`, 'gi');
Sign up to request clarification or add additional context in comments.

Comments

1

Loop through the array with .forEach()

You need to use .html() rather than .text(). Otherwise, you're removing the HTML markup that was added in previous iterations.

You also shouldn't have ' around the word in the :contains() selector.

var colorRed = ['bar', 'foo'];
$(document).ready(function() {
  colorRed.forEach(word =>
    $(".msg:contains(" + word + ")").each(function() {
      var regex = new RegExp(word, 'gi');
      $(this).html($(this).html().replace(regex, "<span class='red'>" + word + "</span>"));
    }));
});
.red {
  color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="msg">select bar and foo in this sentence</div>

Comments

1

Consider the following example.

$(function() {
  function markText(t, m, c) {
    var regex;
    var results = t;
    $.each(m, function(i, el) {
      regex = new RegExp(el, 'gi');
      results = results.replace(regex, "<span class='" + c + "'>" + el + "</span>");
    });
    return results;
  }
  var colorRed = ['bar', 'foo'];
  $(".msg").each(function(idx, elem) {
    $(elem).html(markText($(elem).text().trim(), colorRed, "red"));
  });
});
.red {
  color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="msg">select bar and foo in this sentence</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.