É possível usar nth-child
seletores para envolver 3 divs usando.wrapAll
? Não consigo descobrir a equação correta.
então...
<div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
torna-se...
<div>
<div class="new">
<div></div>
<div></div>
<div></div>
</div>
<div class="new">
<div></div>
<div></div>
<div></div>
</div>
</div>
jquery
css-selectors
wrapall
csbourne
fonte
fonte
Respostas:
Você pode fazer isso com
.slice()
este:var divs = $("div > div"); for(var i = 0; i < divs.length; i+=3) { divs.slice(i, i+3).wrapAll("<div class='new'></div>"); }
Você pode experimentar uma demonstração aqui , tudo o que estamos fazendo aqui é pegar os elementos que você deseja embrulhar e fazer um loop através deles, fazendo um
.wrapAll()
em lotes de 3 e passando para os próximos 3 etc. no entanto, muitos são deixados no final, por exemplo, 3, 3, 3, 2 se for esse o caso.fonte
:nth-child()
se presta bem a isso, quanto a chamar isso, apenas embrulhe-o em um$(function() { });
se quiser executá-lodocument.ready
, caso contrário, chame quando quiser executá-lo :)var divs = $("div > .classname");
OUvar divs = $("div .classname");
ObrigadoEscrevi uma função de bloco genérica que torna isso muito fácil de fazer:
$.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>');
Exibir trecho de código
$.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>
fonte
O Plugin
$(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", ""); } });
Como usá-lo.
Chame
EveryWhat()
o elemento e coloque um número para cada elemento que você gostaria de coletar.$("div").EveryWhat(2).wrapInner('<div class="new" />');
as citações do wrapinner devem ter um formato adequado
<div class="new" />
com classe e tag de fechamento. Stackoverflow me impede de mostrar o que parece, mas aqui está um link de um div de fechamento automático.Como deve ser
Isso envolverá todos os outros números que você especificou. Estou usando o jquery 1.8.2. então lembre-se de usar a chamada do seletor
EveryWhat(3)
e um número para cada vez. Claro, colocá-lo no final da página ou envolvê-lo em um$(document).ready(function() { //place above code here });
Você pode usar cada enésima e,
.wrapInner('<div class="new" />')
em seguida, para os mesmos resultados.fonte
$('div > div:nth-child(3n)')
e não resulta em dois grupos de três elementos.Aqui está uma versão mais utilizável de Nick acima:
window.WrapMatch = function(sel, count, className){ for(var i = 0; i < sel.length; i+=count) { sel.slice(i, i+count).wrapAll('<div class="'+className+'" />'); } }
Você usaria isso como:
var ele = $('#menu > ul > li'); window.WrapMatch(ele, 5, 'new-class-name');
janela deve ser substituída pelo seu namespace Handlers, é claro.
Atualizado: uma versão ligeiramente melhor que aproveita 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 como:
$('.list-parent li').wrapMatch(5,'newclass');
O segundo parâmetro para o nome do wrapper é opcional.
fonte
$(function() { $.fn.WrapThis = function(arg1, arg2) { /*=Takes 2 arguments, arg1 is how many elements to wrap together, arg2 is the element to wrap*/ var wrapClass = "column"; //=Set class name for wrapping element var itemLength = $(this).find(arg2).length; //=Get the total length of elements var remainder = itemLength%arg1; //=Calculate the remainder for the last array var lastArray = itemLength - remainder; //=Calculate where the last array should begin var arr = []; if($.isNumeric(arg1)) { $(this).find(arg2).each(function(idx, item) { var newNum = idx + 1; if(newNum%arg1 !== 0 && newNum <= lastArray){ arr.push(item); } else if(newNum%arg1 == 0 && newNum <= lastArray) { arr.push(item); var column = $(this).pushStack(arr); column.wrapAll('<div class="' + wrapClass + '"/>'); //=If the array reaches arg1 setting then wrap the array in a column arr = []; } else if(newNum > lastArray && newNum !== itemLength){ //=If newNum is greater than the lastArray setting then start new array of elements arr.push(item); } else { //=If newNum is greater than the length of all the elements then wrap the remainder of elements in a column arr.push(item); var column = $(this).pushStack(arr); column.wrapAll('<div class="' + wrapClass + '"/>'); arr = [] } }); } } });
Peguei a ideia do plugin de Kyle e a estendi para quebrar automaticamente e usar dois argumentos. Não funcionou para mim no início, mas eu o coloquei em execução com algumas edições e adições ao código.
Para invocar a função, basta usar o elemento pai do que você deseja agrupar e definir seus argumentos da seguinte maneira.
$('#container').WrapThis(5, 'li');
O primeiro argumento é quantos elementos você deseja agrupar e o segundo argumento é o tipo de elemento que você gostaria de agrupar.
Você pode alterar a classe do elemento de empacotamento na função principal da variável
wrapClass
.fonte
Eu preparei esta resposta para outra pergunta que era uma duplicata desta. Então, talvez minha variante seja útil para alguém:
Acho que a solução para envolver todos os três elementos é:
var $lines = $('.w-col'), // All Dom elelements with class .w-col holder = []; //Collect DOM elelements $lines.each(function (i, item) { holder.push(item); if (holder.length === 3) { $(holder).wrapAll('<div class="w-row" />'); holder.length = 0; } }); $(holder).wrapAll('<div class="w-row" />'); //Wrap last elements with div(class=w-row)
Escrevi o mesmo código em jsbin com algumas melhorias http://jsbin.com/necozu/17/ ou http://jsbin.com/necozu/16/
fonte