1

I have a list of 12 posts wrapped in a div tag and the structure looks like this:

<div class="row">
    <div class="content">
    </div>
    <div class="content">
    </div>
    <div class="content">
    </div>
    <div class="content">
    </div>
    <div class="content">
    </div>
    <div class="content">
    </div>
    <div class="content">
    </div>
    <div class="content">
    </div>
    <div class="content">
    </div>
    <div class="content">
    </div>
    <div class="content">
    </div>
    <div class="content">
    </div>
</div>

Is there a way I can loop every third div with the class of content in another div tag?

At the end I would have my structure like this:

<div class="row">
    <div class="wrapper">
        <div class="content">
        </div>
        <div class="content">
        </div>
        <div class="content">
        </div>
    </div>
    <div class="wrapper">
        <div class="content">
        </div>
        <div class="content">
        </div>
        <div class="content">
        </div>
    </div>
    <div class="wrapper">
        <div class="content">
        </div>
        <div class="content">
        </div>
        <div class="content">
        </div>
    </div>
    <div class="wrapper">
        <div class="content">
        </div>
        <div class="content">
        </div>
        <div class="content">
        </div>
    </div>
</div>

Is there a way I can loop every third div with the class of content in another div tag?

Sidney Sousa
  • 3,378
  • 11
  • 48
  • 99
  • use `$i = 0` then in loop use `$i % 3 ==0` in condition – Devsi Odedra Mar 26 '19 at 08:00
  • 1
    Possible duplicate of [Wrap every 3 divs in a div](https://stackoverflow.com/questions/3366529/wrap-every-3-divs-in-a-div) – Carsten Løvbo Andersen Mar 26 '19 at 08:02
  • 1
    Just curious, how does this HTML getting rendered? If you plan to manipulate the HTML using Javascript after page load, user will face some inconsistency or flickering in the UI. I would have used some front end UI frameworks or template engine for rendering – Dipak Mar 26 '19 at 08:04
  • Do you really need the change in structure? Or would it be sufficient, if you'd be able to change the presentation with CSS? I have the slight idea, that you are asking the wrong question. – yunzen Mar 26 '19 at 08:13

3 Answers3

3

You can do something like this

// get all element at position 1,4,7,...etc and iterate
$('.row .content:nth-child(3n + 1)').each(function() {
   $(this)
        // get all siblings next to it
        .nextAll('.content')
        // get only next 2 elements from it
        .slice(0, 2)
        // combine the current element with it
        .add(this)
         // wrap all elemnts with the div(3 divs)
        .wrapAll('<div class="wrapper">')
})

$('.row .content:nth-child(3n + 1)').each(function() {
  $(this).nextAll('.content').slice(0, 2).add(this).wrapAll('<div class="wrapper">')
})

console.log($('.row')[0].outerHTML)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
</div>

Or you can use jQuery :lt() pseudo-class selector to avoid slice() method.

$('.row .content:nth-child(3n + 1)').each(function() {
  $(this).nextAll('.content:lt(2)').add(this).wrapAll('<div class="wrapper">')
})

$('.row .content:nth-child(3n + 1)').each(function() {
  $(this).nextAll('.content:lt(2)').add(this).wrapAll('<div class="wrapper">')
})

console.log($('.row')[0].outerHTML)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
</div>
Pranav C Balan
  • 113,687
  • 23
  • 165
  • 188
0

Loop through the children, every third child create a new wrapper and add each child in the respective wrapper.

var test = document.querySelector("#test");
var index = 2;
for (var child of test.querySelectorAll(".content")) {
  if (index++ >= 2) {
    var newWrapper = test.appendChild(document.createElement("div"));
    newWrapper.className = "wrapper";
    index = 0;
  }
  test.removeChild(child);
  newWrapper.appendChild(child);
}
console.log(test.innerHTML);
<div class="row" id="test">
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
  <div class="content">
  </div>
</div>
nick zoum
  • 7,216
  • 7
  • 36
  • 80
0

Try this

function WrapUpAllDivs(){
      var CurrentDivs = $(".row",".content");
        for(var i = 0; i < CurrentDivs.length -1 ; i+=3) {
          CurrentDivs
           .slice(i, i+3)
           .wrapAll("<div class=\"wrapper\"></div>"); 
    }
}
AhmadMM
  • 371
  • 4
  • 16