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);
}