web-dev-qa-db-fra.com

Envelopper toutes les 3 divisions dans une division

Est-il possible d'utiliser nth-child sélecteurs pour encapsuler 3 div à l'aide de .wrapAll? Je n'arrive pas à trouver la bonne équation.

alors...

<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>
83
csbourne

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 est d'obtenir les éléments que vous souhaitez envelopper et de les parcourir, en faisant .wrapAll() par lots de 3, puis passer aux 3 suivants, etc. Il enveloppera 3 à la fois et cependant il en restera beaucoup à la fin, par exemple 3, 3, 3, 2 si tel est le cas.

177
Nick Craver

J'ai écrit une fonction générique de morceau qui rend cela assez facile à faire:

$.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>
19
Ja͢ck

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.

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

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

les citations de wrapinner doivent avoir un <div class="new" /> correctement formaté avec une classe et une balise de fermeture. Stackoverflow m'empêche de montrer à quoi cela ressemble, mais voici le lien d'un div à fermeture automatique.

À quoi cela devrait ressembler

Cela encapsulera tous les autres numéros que vous avez spécifiés. J'utilise jquery 1.8.2. n'oubliez donc pas d'utiliser le sélecteur appel EveryWhat(3) et un numéro à chaque fois. Bien sûr, le mettre en bas de la page ou l'envelopper dans un

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

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

8
Alex Williams

Voici une version plus utilisable 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 utiliseriez ceci comme:

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

la fenêtre doit être remplacée par votre espace de noms Handlers, bien sûr.

Mise à jour: une version légèrement meilleure qui exploite 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);

Utilisez comme:

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

Le deuxième paramètre pour le nom de l'encapsuleur est facultatif.

7
Pat
$(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 pris l'idée du plugin de Kyle et l'ai étendu pour envelopper automatiquement et prendre deux arguments. Cela n'a pas fonctionné pour moi au début, mais je l'ai exécuté avec quelques modifications et ajouts au code.

Pour appeler la fonction, utilisez simplement l'élément parent de ce que vous voulez encapsuler, puis définissez vos arguments comme suit.

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

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

Vous pouvez changer la classe de l'élément d'habillage dans la fonction principale sous la variable wrapClass.

1
PixelPrecision

J'ai préparé cette réponse pour une autre question qui était en double de celle-ci. Alors peut-être que ma variante sera utile pour quelqu'un:

Je pense que la solution pour envelopper les trois éléments est:

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)

J'ai écrit le même code sur jsbin avec quelques améliorations http://jsbin.com/necozu/17/ ou http://jsbin.com/necozu/16/

0
Chekit