¿Es posible usar nth-child
selectores para envolver 3 divs usando .wrapAll
? Parece que no puedo resolver la ecuación correcta.
entonces...
<div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
se convierte en ...
<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
fuente
fuente
Respuestas:
Puedes hacerlo con
.slice()
, así:var divs = $("div > div"); for(var i = 0; i < divs.length; i+=3) { divs.slice(i, i+3).wrapAll("<div class='new'></div>"); }
Puede probar una demostración aquí , todo lo que estamos haciendo aquí es obtener los elementos que desea envolver y recorrerlos, hacer un
.wrapAll()
lote de 3 y luego pasar a los siguientes 3, etc. sin embargo, quedan muchos al final, por ejemplo, 3, 3, 3, 2 si ese es el caso.fuente
:nth-child()
no se presta bien a esto, en cuanto a llamar a esto, simplemente envuélvalo en un$(function() { });
si desea ejecutarlodocument.ready
, de lo contrario, llámelo cuando quiera ejecutarlo :)var divs = $("div > .classname");
Ovar divs = $("div .classname");
GraciasEscribí una función de fragmento genérico que hace que esto sea bastante fácil de hacer:
$.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>');
Mostrar fragmento 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>
fuente
El complemento
$(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", ""); } });
Cómo usarlo.
Llame
EveryWhat()
al elemento e ingrese un número para cada elemento que le gustaría recolectar.$("div").EveryWhat(2).wrapInner('<div class="new" />');
Las citas de wrapinner deben tener un formato adecuado
<div class="new" />
con una clase y una etiqueta de cierre. Stackoverflow me impide mostrar cómo se ve, pero aquí hay un enlace de un div de cierre automático.Como debería verse
Eso ajustará todos los demás números que especificó. Estoy usando jquery 1.8.2. así que recuerde usar el selector de llamadas
EveryWhat(3)
y un número para cada vez. Por supuesto, ponerlo al final de la página o envolverlo en un$(document).ready(function() { //place above code here });
Puede usar cada enésimo y luego
.wrapInner('<div class="new" />')
para obtener los mismos resultados.fuente
$('div > div:nth-child(3n)')
y en realidad no resulta en dos grupos de tres elementos.Aquí hay una versión más útil de la de Nick anterior:
window.WrapMatch = function(sel, count, className){ for(var i = 0; i < sel.length; i+=count) { sel.slice(i, i+count).wrapAll('<div class="'+className+'" />'); } }
Usaría esto como:
var ele = $('#menu > ul > li'); window.WrapMatch(ele, 5, 'new-class-name');
La ventana debe ser reemplazada por su espacio de nombres Handlers, por supuesto.
Actualizado: una versión ligeramente mejor que aprovecha 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);
Usar como:
$('.list-parent li').wrapMatch(5,'newclass');
El segundo parámetro para el nombre del contenedor es opcional.
fuente
$(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 = [] } }); } } });
Tomé la idea del complemento de Kyle y la extendí para ajustar automáticamente y tomar dos argumentos. Para empezar, no me funcionó, pero lo hice funcionar con algunas ediciones y adiciones al código.
Para invocar la función, simplemente use el elemento padre de lo que desea ajustar y luego configure sus argumentos de la siguiente manera.
$('#container').WrapThis(5, 'li');
El primer argumento es cuántos elementos desea envolver juntos y el segundo argumento es el tipo de elemento que desea envolver.
Puede cambiar la clase del elemento de envoltura en la función principal bajo la variable
wrapClass
.fuente
He preparado esta respuesta para otra pregunta que era un duplicado de esta. Entonces, tal vez mi variante sea útil para alguien:
Creo que la solución para envolver los tres elementos es:
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)
Escribí el mismo código en jsbin con algunas mejoras http://jsbin.com/necozu/17/ o http://jsbin.com/necozu/16/
fuente