Wrapping words in HTML with spans
And making them highlightable!
HTML
<div id="words">
<p>
If your element contents contains child elements (HTML) then the above solutions are not useful.
</p>
<p>
Here's a <strong class="jsfiddle">jsfiddle</strong> I've come up with that preserves HTML (elements and their attributes). The shortcoming of this small snippet is that if you have events binded to the element's contents then they will be lost since innerHTML is being reassigned to something else.
</p>
<p>
This code does not require any special libraries (like <i>jQuery</i>).
</p>
<p>
<a href="https://jsfiddle.net/4b5j0wjo/3/">https://jsfiddle.net/4b5j0wjo/3/</a>
</p>
<code><pre>
var e = document.getElementById('words');
e.innerHTML = e.innerHTML.replace(/(^|<\/?[^>]+>|\s+)([^\s<]+)/g, '$1<span class="word">$2</span>');
</pre></code>
</div>
<hr>
<div id="highlighted">
Highlighted: 0
</div>
CSS
.word:hover {
background-color: rgba(0,0,0,0.1);
}
.word.highlighted {
background-color: yellow;
}
JavaScript
var e = document.getElementById('words');
var t = document.getElementById('highlighted');
e.innerHTML = e.innerHTML.replace(/(^|<\/?[^>]+>|\s+)([^\s<]+)/g, '$1<span class="word">$2</span>');
e.addEventListener('click', function(ev) {
if (ev.target.classList.contains('word')) {
ev.target.classList.toggle('highlighted');
highlighted.innerHTML = 'Highlighted: ' + e.querySelectorAll('.highlighted').length;
}
}, true);