84 votes

Envelopper toutes les 3 divs dans une div

Est-il possible d'utiliser nth-child pour envelopper 3 divs en utilisant .wrapAll ? Je n'arrive pas à trouver l'équation correcte.

donc...

<div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
</div>

devient...

<div>
   <div class="new">
        <div></div>
        <div></div>
        <div></div>
   </div>
   <div class="new">
        <div></div>
        <div></div>
        <div></div>
   </div>
</div>

179voto

Nick Craver Points 313913

Vous pouvez le faire avec .slice() comme ceci :

var divs = $("div > div");
for(var i = 0; i < divs.length; i+=3) {
  divs.slice(i, i+3).wrapAll("<div class='new'></div>");
}

Vous pouvez essayer une démo ici tout ce que nous faisons ici, c'est récupérer les éléments que nous voulons envelopper et les parcourir en boucle, en faisant un .wrapAll() par lots de 3, puis en passant aux 3 suivants, etc. Il s'agira de 3 à la fois et il en restera autant à la fin, par exemple 3, 3, 3, 2 si c'est le cas.

23voto

Jack Points 88446

J'ai écrit une fonction générique qui facilite cette tâche :

$.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>

8voto

Alex Williams Points 98

Le 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", "");
    }
});

Comment l'utiliser ?

Appeler EveryWhat() sur l'élément et inscrivez un numéro pour chaque élément que vous souhaitez collecter.

$("div").EveryWhat(2).wrapInner('<div class="new" />');

Les citations de wrapinner doivent être correctement formatées. <div class="new" /> avec une classe et une balise de fermeture. Stackoverflow m'empêche de montrer à quoi cela ressemble mais voici un lien d'une div qui se ferme d'elle-même.

À quoi doit-il ressembler ?

Cela englobera tous les autres numéros que vous avez spécifiés. J'utilise jquery 1.8.2. donc n'oubliez pas d'utiliser l'appel de sélecteur EveryWhat(3) et un numéro pour chaque fois. Bien entendu, le fait de le placer au bas de la page ou de l'envelopper dans une page d'accueil permet d'éviter toute confusion.

$(document).ready(function() {  
    //place above code here
});

Vous pourriez utiliser chaque nième et ensuite .wrapInner('<div class="new" />') pour les mêmes résultats.

7voto

Pat Points 97

Voici une version plus utilisable de celle de Nick ci-dessus :

window.WrapMatch = function(sel, count, className){
  for(var i = 0; i < sel.length; i+=count) {
    sel.slice(i, i+count).wrapAll('<div class="'+className+'" />');
  }
}

Vous l'utiliserez de la manière suivante :

var ele = $('#menu > ul > li'); 
window.WrapMatch(ele, 5, 'new-class-name');

doit être remplacée par votre espace de noms Handlers, bien entendu.

Mise à jour : Une version légèrement améliorée qui s'appuie sur 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);

Utiliser comme :

$('.list-parent li').wrapMatch(5,'newclass');

Le deuxième paramètre du nom de l'enveloppe est facultatif.

1voto

PixelPrecision Points 1
$(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 = []
                }
            });
        }
    }
});

J'ai repris l'idée du plugin de Kyle et je l'ai étendu pour qu'il s'intègre automatiquement et prenne deux arguments. Cela n'a pas fonctionné pour moi au début, mais j'ai réussi à le faire fonctionner avec quelques modifications et ajouts au code.

Pour invoquer la fonction, il suffit d'utiliser l'élément parent de ce que vous voulez envelopper et de définir vos arguments comme suit.

$('#container').WrapThis(5, 'li');

Le premier argument est le nombre d'éléments que vous souhaitez regrouper et le deuxième argument est le type d'élément que vous souhaitez regrouper.

Vous pouvez modifier la classe de l'élément enveloppant dans la fonction principale sous la variable wrapClass .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X