JSFiddle - React, Tailwind, and code Playground
HTML
The word colored will be formated as <font color="red">colored</font>, and the word highlighting will be formated as <span style="background-color: yellow">highlighting</span> in real time.
<div id="textarea" contenteditable>This is an editable <font color="red">colored</font> text area with <span style="background-color: yellow">highlighting</span>.</div>
CSS
#textarea {
-moz-appearance: textfield-multiline;
-webkit-appearance: textarea;
border: 1px solid gray;
font: medium -moz-fixed;
font: -webkit-small-control;
font-family: "Courier New", monospace;
height: 50px;
overflow: auto;
padding: 2px;
resize: both;
width: 400px;
}
JavaScript
$(function(){
var prevText = "";
var isHighlighting = false;
$("#textarea").bind("paste drop keypress input textInput DOMNodeInserted", function (e){
if (!isHighlighting)
{
var currentText = $(this).text();
if (currentText != prevText)
{
doSave();
isHighlighting = true;
$(this).html(currentText
.replace(/\bcolored\b/g, "<font color=\"red\">colored</font>")
.replace(/\bhighlighting\b/g, "<span style=\"background-color: yellow\">highlighting</span>"));
isHighlighting = false;
prevText = currentText;
doRestore();
}
}
});
});
var saveSelection, restoreSelection;
if (window.getSelection && document.createRange) {
saveSelection = function(containerEl) {
var range = window.getSelection().getRangeAt(0);
var preSelectionRange = range.cloneRange();
preSelectionRange.selectNodeContents(containerEl);
preSelectionRange.setEnd(range.startContainer, range.startOffset);
var start = preSelectionRange.toString().length;
return {
start: start,
end: start + range.toString().length
}
};
restoreSelection = function(containerEl, savedSel) {
var charIndex = 0, range = document.createRange();
range.setStart(containerEl, 0);
range.collapse(true);
var nodeStack = [containerEl], node, foundStart = false, stop = false;
while (!stop && (node = nodeStack.pop())) {
if (node.nodeType == 3) {
var nextCharIndex = charIndex + node.length;
if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
range.setStart(node, savedSel.start - charIndex);
foundStart = true;
}
if (foundStart &&...