var colors = ['yellow', 'red', 'lightgreen', 'cyan'];
var currentColor = 0;
// Create a text node using Unicode Character 'NO-BREAK SPACE' (U+00A0)
var $spaceNode = $(document.createTextNode('\u00A0'));
// Wrap the text node to a span with a begin and end sibling of the space text node clone
var $elem = $('<span>').append(
$spaceNode.clone(),
$('<span>', {
'data-function': "addSynonym",
'data-options': '[test1, test2, test3]',
'html': $('<span>', {
'text': 'test4',
'css': {
backgroundColor: 'yellow'
}
})
}),
$spaceNode.clone()
);
function appendText() {
// Output $elem node outer HTML to a preview element
$('#elem_html').text($elem[0].outerHTML);
// Clone the $elem so we can use it multiple times
var $elemClone = $elem.clone();
// Append the cloned $elem to the DOM
$('#editor').append($elemClone);
// Apply manipulation demo timer
hookElemChange($elemClone);
}
// Handle add text button click
$('#add_text').on('click', function() {
appendText();
});
// Handle change $elem color button click
$('#change_text_color').on('click', function() {
var newColor;
// Generate a random color
do {
newColor = Math.floor(Math.random() * Math.floor(colors.length));
} while(newColor === currentColor);
currentColor = newColor;
// Change the $elem inner span background color to a random color
$elem.find('span > span').css('background-color', colors[currentColor]);
// We can also use specific element selector using data-function with "addSynonym" value
// $elem.find('span[data-function="addSynonym"] > span').css('background-color', colors[currentColor]);
// Append the text to the DOM
appendText();
});
// A timer for each element that parses and increases the text prepending number
// This is for to demontrate that each node can be manipulated with no restrictions after creating/cloning
function hookElemChange($element) {
setInterval(function() {
var $currentElem = $element.find('span[data-function="addSynonym"] > span');
var text = $currentElem.text();
var textParts = text.match(/([a-z]+)(\d+)/);
if (textParts) {
var num = parseInt(textParts[2]);
var newText = textParts[1] + ++num;
$currentElem.text(newText);
}
}, 1000);
}
#editor {
border: 1px solid grey;
height: 100px;
margin-bottom: 10px;
overflow-wrap: break-word;
overflow: auto;
}
#elem_html {
white-space: normal;
margin-top: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="editor"></div>
<div>
<button id="add_text">Add text</button>
<button id="change_text_color">Change color</button>
</div>
<div>
<pre id="elem_html"></pre>
</div>