JSFiddle - React, Tailwind, and code Playground
by lid0
HTML
<pre>
break text nodes into smaller text nodes by word, and wrap in span
</pre>
<div id="container">
this is some content <b id="link">click</b> this, here is some more
<kb>aaa<kb>bbb</kb>ccc</kb>
</div>
<div id="container2"></div>
CSS
#container2{
margin-top:10px;
border: 1px solid orange;
}
#container2 span {
background:#cfcfcf;
padding:5px;
margin:3px;
border-radius:11px;
}
JavaScript
var c = document.getElementById("container")
var c2 = document.getElementById("container2")
var b = document.getElementById("link")
var s = document.createElement('span')
b.addEventListener('click', function() {
alert("clicked")
})
function wrapTextNodeInSpan(parent) {
// create a Text Node iterator on the parent element
var iter = document.createNodeIterator(parent, NodeFilter.SHOW_TEXT);
var textnode;
var nodes = []
// find all text nodes
while (textnode = iter.nextNode()) {
// split content of node to smaller text nodes.
nodes.push(...splitTextToNodes(textnode.textContent))
}
var spans = nodes.map(function(v) {
var spanEl = document.createElement("span")
spanEl.append(v)
return spanEl
})
return spans
}
/*
splitTextToNodes split string by spaces and return an array of textNode
*/
function splitTextToNodes(text) {
// split and ignore empty or newline only parts.
var s = text.split(" ").filter(v => !(v == "" || v == "\n"))
// preserve space for each part
s = s.map((v) => {
return v + " "
})
// remove space from last element
if (s.length > 1) {
var lst = s[s.length - 1];
s[s.length - 1] = lst.substr(0, lst.length - 1)
}
// create TextNode from parts.
var nodes = []
s.forEach(v => nodes.push(document.createTextNode(v)))
return nodes;
}
// take each word from container1 and turn into "span bubbles" in container2
c2.append(...wrapTextNodeInSpan(c))
// NOT USED
// move all children of a parent element to a new span element
function wrapSpan(parent) {
let s = document.createElement("span");
s.append(...parent.childNodes);
c.append(s);
}