skip to Main Content

I want to make a script that highlights certain text using predefined color mapping.

For this case I want the tags from myDiv to be highlighted with their corresponding colors from tagColors object

const tagColors = {
  "#tag": "#00ccff",
  "#tagAgain": "#ff0808"
};

const tags = Object.keys(tagColors).sort((a, b) => b.length - a.length);
let text = document.getElementById("myDiv").innerHTML;

for (const tag of tags) {
  text = text.replace(new RegExp(`\${tag}`, "g"), highlight(tag));
}

function highlight(tag) {
  return `<span style='color:${tagColors[tag]}'>$&</span>`;
}

document.getElementById("myDiv").innerHTML = text;
<div id="myDiv">
  This is some text with #tag, #tags, #tagtag, #notListed and #tagAgain.
</div>

The problem is that #tagAgain gets highlighted separately: the #tag is #00ccff and the Again is #ff0808.

I did try changing the regex to \${tag}\b, but it doesn’t highlight the #tag in #tags. I want it to still be highlighted if the tag is continued with other words (leaving the extra words to be not highlighted.)

2

Answers


  1. You try to for..in the array (Object.keys()). So the code fails since you get integer indices instead of tag names.

    const tagColors = {
      "tag": "#00ccff",
      "tagAgain": "#ff0808"
    };
    
    let text = document.getElementById("myDiv").innerHTML;
    
    
    const tags = Object.keys(tagColors).sort((a,b) => b.length - a.length).map(escapeRegex).join('|');
    text = text.replace(new RegExp(`#(${tags})`, "g"), (_, tag) => `<span style='color:${tagColors[tag]}'>#${tag}</span>`);
    
    //https://stackoverflow.com/a/3561711/14098260
    function escapeRegex(string) {
        return string.replace(/[/-\^$*+?.()|[]{}]/g, '\$&');
    }
    
    document.getElementById("myDiv").innerHTML = text;
    <div id="myDiv">
      This is some text with <#tag>s #tag++, #tags, #tagtag, #notListed and #tagAgain.
    </div>
    Login or Signup to reply.
  2. How about css? Here’s your example and some styling:

    const tagColors = {
      "#tag": "#00ccff",
      "#tagAgain": "#ff0808"
    };
    
    const tags = Object.keys(tagColors).sort((a, b) => b.length - a.length);
    let text = document.getElementById("myDiv").innerHTML;
    
    for (const tag of tags) {
      text = text.replace(new RegExp(`\${tag}`, "g"), highlight(tag));
    }
    
    function highlight(tag) {
      return `<span style='color:${tagColors[tag]}'>$&</span>`;
    }
    
    document.getElementById("myDiv").innerHTML = text;
    #myDiv span span {
      color: inherit!important;
    }
    <div id="myDiv">
      This is some text with #tag, #tags, #tagtag, #notListed and #tagAgain.
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search