Home > other >  How can I merge three html elements
How can I merge three html elements

Time:11-17

Say I have the following structure:

<p>lorem ipsum</p>
<span>dolor</span>
<p>sit amen</p>

What is the best way to programmatically get the following in JS?

<p>lorem ipsum <span>dolor</span> sit amen</p>

Is it possible also to do this with differents tags like

<h1>lorem ipsum</h1>
<span>dolor</span>
<h1>sit amen</h1>

That should result in

<h1>lorem ipsum <span>dolor</span> sit amen</h1>

I'm not talking just of three elements: could be also something like:

p
span
p
span
p

CodePudding user response:

This solution can use in any number of elements, the elements will be merged with the tag of the first element, in case the element have the same tag of the first element, it will be merged with it's textContent if not it will be appended with it's tag.

const container = document.querySelector('.container')
const [first, ...rest] = container.children;
const result = rest.reduce((acc, child) => {
  if (child.tagName === first.tagName) {
    first.appendChild(document.createTextNode(' '  
    child.textContent));
  } else {
    first.appendChild(document.createTextNode(' '));
    first.appendChild(child);
  }
  return acc;
}, first)


container.innerHTML = ''
container.appendChild(result)
<div >
  <h1>lorem ipsum</h1>
  <span>dolor</span>
  <h1>sit amen</h1>
  <span>dolor2</span>
  <h1>sit amen2</h1>
</div>

CodePudding user response:

You can try this code.

const h1tag = document.createElement("h1");
const node = document.createTextNode( 
    document.querySelectorAll("h1")[0].innerHTML   " "   
    document.querySelector("span").outerHTML   " "   
    document.querySelectorAll("h1")[1].innerHTML  
    );
h1tag.appendChild(node);

CodePudding user response:

You could do something like this:

const inPnl = document.getElementById('input');
const elems = inPnl.querySelectorAll('p, span');
const outPnl = document.getElementById('output');

elems[0]
  .appendChild(elems[1])
  .appendChild(document.createTextNode(elems[2].innerText));

outPnl.appendChild(elems[0]);
<em>input:</em>
<div id=input>
<p>lorem ipsum</p>
<span>dolor</span>
<p>sit amen</p>
</div>

<em>output:</em>
<div id=output>
</div>

Replace p with h1 in query selector, as needed.

CodePudding user response:

So as it might be <p> or <h1> tags or something I assume you can add containers around the elements that need to be restructured. If so, you could do something generic like this.

function restructure()
{
  // get all divs that needs to be restructured
  let divsToRestructure = document.querySelectorAll('.default-structure');

  divsToRestructure.forEach(divToRestructure => {
      // do what needs to happen to restructure a div
      let elements = divToRestructure.querySelectorAll('*');
      let parentTag = elements[0].tagName;

      // create the element that needs to contain the new structure
      let newStructure = document.createElement(parentTag);

      // add all old elements in the new structure
      elements.forEach(element => {
        if(element.tagName == parentTag){
          newStructure.innerHTML  = element.innerHTML;
        }
        else
        {
          newStructure.appendChild(element);
        }
        newStructure.innerHTML  = ' ';
    })
    
    
    // clear the default-structured div
    divToRestructure.innerHTML = '';
    // add the new structure to the div
    divToRestructure.appendChild(newStructure);
    divToRestructure.classList.remove('default-structure');
    divToRestructure.classList.add('new-structure');
  });
}
div { border: solid black 1px; }
span { font-style: italic; }
<button onclick="restructure()">Restructure</button>

<div >
  <p>lorem ipsum</p>
  <span>dolor</span>
  <p>sit amen</p>
</div>

<div >
  <h1>lorem ipsum</h1>
  <span>dolor</span>
  <h1>sit amen</h1>
</div>

<div >
  <p>lorem ipsum</p>
  <span>dolor</span>
  <p>sit amen</p>
  <span>consectetur</span>
  <p>adipiscing elit</p>
</div>

  • Related