user15788060
user15788060

Reputation:

Change color of specific word while typing on contenteditable="true"

I'm trying to do something interesting, for example, I have a div with contenteditable="true", and want while writing to change the color of a specific word I write, in the example below the word "typing", for example, the normal text color is white, and the highlighted color text is red.

<div class="text-area" contenteditable="true">
 start typing here...
</div>

Any ideas devs, I would like as Vanilla Js or with a framework doesn't matter.

Upvotes: 1

Views: 996

Answers (1)

LuisAFK
LuisAFK

Reputation: 957

You can have a dictionary/object with keywords, each with an assigned color.

let main = document.querySelector('div#main');
let outp = document.querySelector('div#output');

// Colors to replace
const colors = ['red', 'yellow', 'blue', 'green', 'magenta', 'purple', 'black', 'white', 'grey', 'gray', 'cyan', 'orange', 'crimson', 'salmon', 'pink', 'violet', 'turquoise', 'firebrick', 'gainsboro', 'honeydew', 'ivory', 'indigo', 'lavender', 'lime', 'linen', 'maroon'];
const keywords = {
  cool: 2,
  'black cat': 8,
  happy: 1
};

// When user enters something, style it
main.addEventListener('input', function(e)
{
  outp.innerText = this.innerText;

  for (let i = 0; i < Object.keys(keywords).length; i++)
  {
    const keywords_ = Object.keys(keywords);
    const keyword = keywords_[i];
    const color = colors[keywords[keyword]];
    
    outp.innerHTML = outp.innerHTML.replaceAll(new RegExp('(' + keyword + ')', 'gi'), '<span style="color: ' + color + ';">$1</span>');
  }
});

// Style initial values
main.dispatchEvent(new Event('input'));

main.addEventListener('click', outp.focus);

outp.style.top  = main.offsetTop .toString() + 'px';
outp.style.left = main.offsetLeft.toString() + 'px';
div#main
{
  /*position: absolute;
  z-index: 50;*/
  
  /*display: none;*/
  color: transparent;
}

div#main::selection
{
  color: transparent;
  background: transparent;
}

div#main
{
  position: fixed;
  z-index: 50;
}

div#output
{
  border: 1px solid grey;
}

div#main, div#output
{
  outline: none;
  
  min-width: 3cm;
  min-height: 1cm;
  
  max-width: 90vw;
  max-height: 90vh;
  
  padding: 5px;
}
<div id="container">
  <div contenteditable="true" id="main">
    Please enter something cool, like a happy black cat
  </div>

  <div contenteditable="false" id="output">

  </div>
</div>

Upvotes: 1

Related Questions