How does one wrap multiple div-elements around another element-node using vanilla JavaScript and the Node-API only?

Viewed 221

I am using the reference of the post enter link description here

I am curious that how to do the multiple wrapping the ul with div concept in vanilla javascript.

The code I have tried so far is

   const firstOrder = document.createElement('div');
    const secondOrder = document.createElement('div');
    firstOrder.classList.add("someClass");
    secondOrder.classList.add("random");
    const theParentNode = document.querySelector('.main-nav');
    firstOrder.insertAdjacentElement('afterbegin', document.querySelector('.ul-0'));
    secondOrder.insertAdjacentHTML('afterbegin', document.querySelector('.someClass'));
    theParentNode.appendChild(firstOrder, secondOrder);
<nav class="main-nav">
    <ul class="main-nav-list ul-0">
        <li class="a"> <a href="/">First</a>
            <ul class="main-nav-list">
                <li class="b"> <a href="/">Type of menu</a>
                    <ul class="main-nav-list">
                        <li class="c"> <a href="/">Summer</a> </li>
                        <li class="c"> <a href="/">Winter</a> </li>
                        <li class="c"> <a href="/">All season</a> </li>
                        <li class="c"> <a href="/">Spring </a> </li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
</nav>

Any help will be appreciated thanks !!

2 Answers

Writing some helpers does help achieving the task in a maybe more readable and also less repetitive way ...

function removeAndReturn(targetNode) {
  return targetNode.parentNode.removeChild(targetNode);
}
function insertBefore(targetNode, newNode) {
  targetNode.parentNode.insertBefore(newNode, targetNode);
}
function wrapAround(targetNode, wrapperNode) {
  insertBefore(targetNode, wrapperNode);
  wrapperNode.appendChild(removeAndReturn(targetNode));
}
const firstOrder = document.createElement('div');
const secondOrder = document.createElement('div');

firstOrder.classList.add("someClass");
secondOrder.classList.add("random");

// wrap `secondOrder` container around the main navigation.
wrapAround(document.querySelector('ul.ul-0'), secondOrder);

// wrap `firstOrder` container around the `secondOrder` one.
wrapAround(secondOrder, firstOrder);
.someClass {
  /* kind of orange */
  border: 1px solid #fc0;
  padding: 2px;
}
.random {
  /* somehow greenish */
  border: 1px solid #0fc;
}
<nav class="main-nav">
  <ul class="main-nav-list ul-0">
    <li class="a"> <a href="/">First</a>
      <ul class="main-nav-list">
        <li class="b"> <a href="/">Type of menu</a>
          <ul class="main-nav-list">
            <li class="c"> <a href="/">Summer</a> </li>
            <li class="c"> <a href="/">Winter</a> </li>
            <li class="c"> <a href="/">All season</a> </li>
            <li class="c"> <a href="/">Spring </a> </li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</nav>

Edit

"How to achieve this in all ul>li with the same scenario dyanmically. can you please guide? – Script Host"

function removeAndReturn(targetNode) {
  return targetNode.parentNode.removeChild(targetNode);
}
function insertBefore(targetNode, newNode) {
  targetNode.parentNode.insertBefore(newNode, targetNode);
}
function wrapAround(targetNode, wrapperNode) {
  insertBefore(targetNode, wrapperNode);
  wrapperNode.appendChild(removeAndReturn(targetNode));
}
const firstOrder = document.createElement('div');
const secondOrder = document.createElement('div');

firstOrder.classList.add("someClass");
secondOrder.classList.add("random");

document
  .querySelectorAll('ul')
  .forEach(elmNode => {
  
    const outerUlWrapper = firstOrder.cloneNode();
    const innerUlWrapper = secondOrder.cloneNode();

    // wrap inner `secondOrder` clone around the current list node.
    wrapAround(elmNode, innerUlWrapper);

    // wrap outer `firstOrder` clone around the `secondOrder` clone.
    wrapAround(innerUlWrapper, outerUlWrapper);
  });
.someClass {
  /* kind of orange */
  border: 1px solid #fc0;
  padding: 2px;
}
.random {
  /* somehow greenish */
  border: 1px solid #0fc;
}
<nav class="main-nav">
  <ul class="main-nav-list ul-0">
    <li class="a"> <a href="/">First</a>
      <ul class="main-nav-list">
        <li class="b"> <a href="/">Type of menu</a>
          <ul class="main-nav-list">
            <li class="c"> <a href="/">Summer</a> </li>
            <li class="c"> <a href="/">Winter</a> </li>
            <li class="c"> <a href="/">All season</a> </li>
            <li class="c"> <a href="/">Spring </a> </li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</nav>

To create a new element:

const div = document.createElement('div');

To give it a CSS class:

div.classList.add('someClass');

To find a particular element in the DOM:

const theParentNode = document.querySelector( [[put a CSS selector here]] );

To add an element as a child of another:

theParentNode.appendChild(div);

Note that adding an element as a child of another will move it from its current location.

A combination of these things will get you what you're after.

Related