Is it possible to use nth-child
selectors to wrap 3 divs using .wrapAll
? I can't seem to work out the correct equation.
so...
<div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
becomes...
<div>
<div class="new">
<div></div>
<div></div>
<div></div>
</div>
<div class="new">
<div></div>
<div></div>
<div></div>
</div>
</div>
You can do it with .slice()
, like this:
var divs = $("div > div");
for(var i = 0; i < divs.length; i+=3) {
divs.slice(i, i+3).wrapAll("<div class='new'></div>");
}
You can try out a demo here, all we're doing here is getting the elements you want to wrap and looping through them, doing a .wrapAll()
in batches of 3 then moving to the next 3, etc. It will wrap 3 at a time and however many are left at the end, e.g. 3, 3, 3, 2 if that's the case.
I've written a generic chunk function that makes this quite easy to do:
$.fn.chunk = function(size) {
var arr = [];
for (var i = 0; i < this.length; i += size) {
arr.push(this.slice(i, i + size));
}
return this.pushStack(arr, "chunk", size);
}
$("div > div").chunk(3).wrap('<div class="new"></div>');
$.fn.chunk = function(size) {
var arr = [];
for (var i = 0; i < this.length; i += size) {
arr.push(this.slice(i, i + size));
}
return this.pushStack(arr, "chunk", size);
}
$("div > div").chunk(3).wrap('<div class="new"></div>');
div > div {
width: 50px;
height: 50px;
background: blue;
margin: 2px;
float: left;
}
div.new {
background: red;
height: auto;
width: auto;
overflow: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
$(function() {
$.fn.EveryWhat = function(arg1) {
var arr = [];
if($.isNumeric(arg1)) {
$.each(this, function(idx, item) {
var newNum = idx + 1;
if(newNum%arg1 == 0)
arr.push(item);
});
}
return this.pushStack(arr, "EveryWhat", "");
}
});
Call EveryWhat()
on the element and put in a number for every element you would like to collect.
$("div").EveryWhat(2).wrapInner('<div class="new" />');
wrapinner's quotes should have a properly formatted <div class="new" />
with a class and closing tag. Stackoverflow prevents me from showing what that looks like but here is a link of a self closing div.
That will wrap every other number that you specified. I'm using jquery 1.8.2. so remember use selector call EveryWhat(3)
and a number for every time. Of course putting it at the bottom of the page or wrapping it in a
$(document).ready(function() {
//place above code here
});
You could use every nth and then .wrapInner('<div class="new" />')
for the same results.
Here is a more usable version of Nick's above:
window.WrapMatch = function(sel, count, className){
for(var i = 0; i < sel.length; i+=count) {
sel.slice(i, i+count).wrapAll('<div class="'+className+'" />');
}
}
You would use this like:
var ele = $('#menu > ul > li');
window.WrapMatch(ele, 5, 'new-class-name');
window should be replaced with your Handlers namespace, of course.
Updated: A slightly better version that leverages jQuery
(function($){
$.fn.wrapMatch = function(count, className) {
var length = this.length;
for(var i = 0; i < length ; i+=count) {
this.slice(i, i+count).wrapAll('<div '+((typeof className == 'string')?'class="'+className+'"':'')+'/>');
}
return this;
};
})(jQuery);
Use like:
$('.list-parent li').wrapMatch(5,'newclass');
The second parameter for the wrapper name is optional.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With