How to extract nested html element to the same level in js

I use javascript and have a div element with some html tags inside it, as shown below, some of the elements are nested and I want to keep them at the same level, the first html looks like this:

<div>
  <p>
    some text on here 1
    <i>
      some italic 
      <b>text</b>
      here
    </i> text text text
  </p>
  <b>
    some bold text on here
  </b>
</div>
Run codeHide result

I don't know how I can extract these nested elements and keep them at the same level, something like this:

<div>
  <p>
    some text on here 1
  </p>
  <i>
    some italic 
  </i>
  <b>text</b>
  <i>
    here
  </i>
  <p>
    text text text
  </p>
  <b>
    some bold text on here
  </b>
</div>
Run codeHide result

update 1

Code performance is not too important!

+4
source share
2 answers

node .cloneNode() true; .childNodes <div>, node .previousElementSibling null .parentElement , push .parentElement .tagName .textContent , .nodeName - #text, .textContent ; .nodeName #text, #text , .outerHTML ; node .tagName #text, node .firstChild node - #text, node .tagName, .firstChild .textContent, , T219 > ;

const clone = document.querySelector("div").cloneNode(true);

let flattenNodes = (el, not = el, res = []) => {
  for (let node of el.childNodes) {
    if (node.nodeName === "#text" && !node.childNodes.length) {
      if (node.previousElementSibling && node.parentElement !== not) {
        let tag = node.parentElement.tagName.toLowerCase();
        res.push(`<${tag}>${node.textContent}</${tag}>`);
      } else {
        res.push(node.textContent);
      }
    }
    if (node.nodeName !== "#text" 
      && Array.from(node.childNodes).every(e => e.nodeName === "#text")) {
        res.push(node.outerHTML);
    } else {
      if (node.tagName && node.tagName !== "#text" 
        && node.firstChild.nodeName === "#text") {
          let tag = node.tagName.toLowerCase();
          res.push(`<${tag}>${node.firstChild.textContent}</${tag}>`);
          node.firstChild.remove();
          flattenNodes(node, not, res);
      }
    }
  }
  return res
}

let res = flattenNodes(clone);

document.querySelector("pre")
.textContent = res.join("");
<div>
  <p>
    some text on here 1
    <i>
      some italic 
      <b>text</b>
      here
    </i> text text text
  </p>
  <b>
    some bold text on here
  </b>
</div>

<pre></pre>
Hide result
+1

? ?

, div div. node, .

const myDiv = document
      .querySelector('#my-div')

const allDescendants = Array.from(myDiv.getElementsByTagName('*'))

allDescendants.forEach(d => {
  myDiv.appendChild(d);
});

console.log(myDiv.innerHTML);
<div id="my-div">
  <p>
    some text on here 1
    <i>
      some italic 
      <b>text</b>
      here
    </i> text text text
  </p>
  <b>
    some bold text on here
  </b>
</div>
Hide result

, , , , . here <i>.

, DFS . , .

const myDiv = document
      .querySelector('#my-div')

const flatDiv = document.createElement('div')
function recurseAndFlatten(parent) {
  parent.childNodes.forEach(child => {
    if (child.nodeType === Node.ELEMENT_NODE) {
      flatDiv.appendChild(child);
      recurseAndFlatten(child);
    }
  });
}

recurseAndFlatten(myDiv);

myDiv.replaceWith(flatDiv);

console.log(flatDiv.innerHTML);
<div id="my-div">
  <p>
    some text on here 1
    <i>
      some italic 
      <b>text</b>
      here
    </i> text text text
  </p>
  <b>
    some bold text on here
  </b>
</div>
Hide result
+1

Source: https://habr.com/ru/post/1674781/


All Articles