0
<body>
    <div class = "order-1-a">
        <div class = "order 2-a">
            <div class = "order 3-a"></div>
        </div>
        <div class = "order 2-b"></div>
        <div class = "order 2-c"></div>
        <div class = "order 2-d"></div>
    </div>
    <div class = "order-1-b"></div>
</body>

If I want a div to wrap only class "order-2-a" + being the first child of "class-1-a", how should I script the div with JavaScript?

difoxy2
  • 59
  • 9
  • You would create a div, append *div.order-2-a* to it, then append it to *div.order-1-a* using [*insertBefore(div.order-2-a, div.order 2-b)*](https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore). PS "2-a" is not a valid class name (see [*Which characters are valid in CSS class names/selectors?*](https://stackoverflow.com/questions/448981/which-characters-are-valid-in-css-class-names-selectors)). – RobG Jan 21 '18 at 22:45

2 Answers2

1

Probably your best bet is to:

  1. Create a new Element with .createElement().
  2. Append 2-a to the new Element with .appendChild().
  3. Insert the new element before 2b with .insertBefore().

var one_a = document.getElementsByClassName("order-1-a")[0];
var two_a = document.getElementsByClassName("order-2-a")[0];
var two_b = document.getElementsByClassName("order-2-b")[0];
var new_node = document.createElement("div");

new_node.appendChild(two_a);
one_a.insertBefore(new_node, two_b);

console.log(one_a.innerHTML);
<body>
  <div class="order-1-a">
    <div class="order-2-a">
      <div class="order-3-a"></div>
    </div>
    <div class="order-2-b"></div>
    <div class="order-2-c"></div>
    <div class="order-2-d"></div>
  </div>
  <div class="order-1-b"></div>
</body>

This provides the structure you're looking for (albeit not displayed well with console.log()).

Also, please be aware that class names cannot start with numbers, and may yield unexpected results. I've updated most of your classes to start with order in my example, as is with your order-1-a class.

Hope this helps!

Obsidian Age
  • 41,205
  • 10
  • 48
  • 71
0

You can create a general wrapping function based on a selector. It should get the subject node, then its parent and either it's next sibling or null if there isn't one.

Then create an element of the required type, append the subject node and insert it before the next sibling or as the last node if there wasn't one.

PS. I've modified the class names to be valid, they can't start with a digit.

// Wrap element with selector in element with tagName
function wrapEl(selector, tagName) {
  var node = document.querySelector(selector);

  // If there is no subject node, return
  if (!node) return;

  // Get parent and sibling (or null if there isn't one)
  var parent = node.parentNode;
  var sibling = node.nextSibling;

  // Append stuff
  var wrapper = document.createElement('tagName');
  wrapper.textContent = 'inserted wrapper'; // Just to show it's there
  wrapper.appendChild(node);
  parent.insertBefore(wrapper, sibling);
}

window.onload = function() {
  wrapEl('.order-2-a', 'div');
}
<body>
    <div class = "order-1-a">
        <div class = "order-2-a">
            <div class = "order-3-a"></div>
        </div>
        <div class = "order-2-b"></div>
        <div class = "order 2-c"></div>
        <div class = "order 2-d"></div>
    </div>
    <div class = "order-1-b"></div>
</body>
RobG
  • 142,382
  • 31
  • 172
  • 209