0

In JavaScript, I would like to split a node to separate text and children. Consider the following node:

<p>text <b>bold</b> and <i>italic</i></p>

I would like to get an array (or something iterable) that looks like:

  1. "text" => text
  2. <b>bold</b> => child
  3. "and" => text
  4. <i>italic</i> => child

How to do this in an efficient and elegant way?

Fifi
  • 3,360
  • 2
  • 27
  • 53
  • 2
    What does "elegant" mean to you? You can already get all of this information via `document.querySelector('p').childNodes`; you would just need to examine the `nodeType` to see if the child is a `textNode`. – Heretic Monkey Mar 24 '20 at 11:58
  • 1
    Elegant means 'nice and short'. Your answer is perfect, exactly what I was looking for. – Fifi Mar 24 '20 at 12:00
  • Does this answer your question? [Best way to get child nodes](https://stackoverflow.com/questions/10381296/best-way-to-get-child-nodes) – Heretic Monkey Mar 24 '20 at 12:36

1 Answers1

2

If you want to get an array of text/HTML for each child node, you can run the children through a switch-statement and check the node type.

Note: Here are all the nodeTypes.

const nodeText = (nodes) => {
  return Array.from(nodes).map(node => {
    switch (node.nodeType) {
      case Node.TEXT_NODE:
        return node.textContent.trim();
      case Node.ELEMENT_NODE:
        return node.outerHTML;
      default:
        return null;
    }
  }).filter(text => text != null);
}

console.log(nodeText(document.querySelector('p').childNodes));
.as-console-wrapper { top: 0; max-height: 100% !important; }
<p>text <b>bold</b> and <i>italic</i></p>
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132