Home > database >  Why wrapping children in a container doesn't work
Why wrapping children in a container doesn't work

Time:01-29

I am trying to wrap the children of some elements in a new div and it's not working. When I loop through the children of the element, the loop only loops through 1 element.

It wraps only one child and leaves the other. Why?

var homepageRows = document.querySelectorAll(".span-12 > *");

homepageRows.forEach(function(row){
    var newRow = document.createElement("div");
    newRow.className = "wrapper-row";

    row.childNodes.forEach(function(child) {
       newRow.appendChild(child); 
    });
    row.append(newRow);
})
  <div >
<div >
    <div>Wrap me in .wrapper-row</div>
    <div>Wrap me in .wrapper-row</div>
</div>
<div >
    <div>Wrap me in .wrapper-row</div>
    <div>Wrap me in .wrapper-row</div>
</div>
<div >
    <div>Wrap me in .wrapper-row</div>
    <div>Wrap me in .wrapper-row</div>
</div>
</div>

CodePudding user response:

One approach is as follows, with some comments in the code to try to explain:

let homepageRows = document.querySelectorAll(".span-12 > *");

homepageRows.forEach(function(row) {
  let newRow = document.createElement("div");
  
  // here we use the Element.classList API to add a new class-name:
  newRow.classList.add("wrapper-row");

  // the easiest change is to simply substitute `row.children` (which retrieves
  // a list of the element-children of the current `row` element-node; we use
  // an Array-literal and the spread operator to convert the iterable HTMLCollection
  // into an Array in order to use Array.prototype.forEach() (there is a
  // NodeList.prototype.forEach(), which is available to chain to the returned
  // value of document.querySelectorAll(), but there is no
  // HTMLCollection.prototype.forEach() which means it's easier to use the Array version.
  [...row.children].forEach(function(child) {
    newRow.appendChild(child);
  });
  row.append(newRow);
})
*,
 ::before,
::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

div {
  border: 2px solid currentColor;
  color: black;
  padding: 1em;
  margin: 1em;
}

.wrapper-row,
.wrapper-row * {
  color: red;
}
<div >
  <div >
    <div>Wrap me in .wrapper-row</div>
    <div>Wrap me in .wrapper-row</div>
  </div>
  <div >
    <div>Wrap me in .wrapper-row</div>
    <div>Wrap me in .wrapper-row</div>
  </div>
  <div >
    <div>Wrap me in .wrapper-row</div>
    <div>Wrap me in .wrapper-row</div>
  </div>
</div>

References:

CodePudding user response:

The return value of querySelectorAll is already an array, namely the array of all elements of that match your query. So in your case, presumably, it's just one. What you want to do, I believe, is not to iterate over that array, but over all children of the first element (the one you want):

var homepageRows = document.querySelectorAll(".span-12 > *");
homepageRows.childNodes.forEach(function(row){
   ...
})
  • Related