Wickeln Sie alle 3 Divs in eine Div

85

Ist es möglich, nth-childSelektoren zu verwenden, um 3 Divs mit zu verpacken .wrapAll? Ich kann anscheinend nicht die richtige Gleichung ausarbeiten.

so...

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

wird...

<div>
   <div class="new">
        <div></div>
        <div></div>
        <div></div>
   </div>
   <div class="new">
        <div></div>
        <div></div>
        <div></div>
   </div>
</div>
csbourne
quelle
2
gist.github.com/3181731 Ein nettes jQuery-Plugin, um genau das zu tun. Ich hoffe, Sie finden es nützlich.
iMoses

Antworten:

179

Sie können es .slice()so machen:

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

Sie können hier eine Demo ausprobieren. Alles, was wir hier tun, ist, die Elemente, die Sie umbrechen möchten, zu erhalten und sie zu durchlaufen, eine .wrapAll()3er-Charge zu erstellen und dann zu den nächsten 3 zu wechseln usw. Es werden jeweils 3 und umbrochen Am Ende bleiben jedoch viele übrig, z. B. 3, 3, 3, 2, wenn dies der Fall ist.

Nick Craver
quelle
Ich würde dies zu einer Funktion machen und die Anzahl der umschlossenen Divs zu einem Argument machen. So etwas wie applyDivGrouping (divs, divsPerGroup);
Stefan Kendall
Beeindruckend! Danke für die schnelle Antwort. Ein paar Dinge ... Also, nur zur Klarstellung - das ist mit dem n-ten Kind nicht möglich? & .. Als kompletter jQuery-Neuling - wie kann ich das zum Laufen bringen? Wickle ich es in eine jQuery (Funktion ($) ...? Vielen Dank
csbourne
@csbourne - Nope eignet :nth-child()sich nicht gut dafür. Um dies zu nennen, wickeln Sie es einfach in ein, $(function() { });wenn Sie es ausführen möchten document.ready, andernfalls rufen Sie es auf , wenn Sie es ausführen möchten :)
Nick Craver
Danke Nick für die fantastische Hilfe und Anleitung - funktioniert perfekt.
Csbourne
3
@Fahad, gemäß der NickCraver-Logik können Sie einfach ein kleines Stück Code bearbeiten var divs = $("div > .classname");ODER var divs = $("div .classname");Danke
23

Ich habe eine generische Chunk-Funktion geschrieben, die dies ganz einfach macht:

$.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>');

Jack
quelle
8

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

Wie man es benutzt.

Rufen Sie EveryWhat()das Element auf und geben Sie eine Nummer für jedes Element ein, das Sie sammeln möchten.

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

Die Anführungszeichen des Wrapinners sollten ordnungsgemäß formatiert sein <div class="new" /> mit einer Klasse und einem schließenden Tag . Stackoverflow hindert mich daran zu zeigen, wie das aussieht, aber hier ist ein Link eines selbstschließenden Div.

Wie es aussehen soll

Damit wird jede andere von Ihnen angegebene Nummer umbrochen. Ich benutze jquery 1.8.2. Denken Sie also daran, EveryWhat(3)jedes Mal einen Wählanruf und eine Nummer zu verwenden. Natürlich am Ende der Seite platzieren oder in a einwickeln

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

Sie könnten jedes n-te und dann .wrapInner('<div class="new" />')für die gleichen Ergebnisse verwenden.

Alex Williams
quelle
1
Sie können dies bereits mit tun $('div > div:nth-child(3n)')und führen nicht zu zwei Gruppen von drei Elementen.
Ja͢ck
7

Hier ist eine benutzerfreundlichere Version von Nick's oben:

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

Sie würden dies wie folgt verwenden:

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

Das Fenster sollte natürlich durch Ihren Handlers-Namespace ersetzt werden.

Aktualisiert: Eine etwas bessere Version, die jQuery nutzt

(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);

Verwenden Sie wie:

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

Der zweite Parameter für den Wrapper-Namen ist optional.

Klopfen
quelle
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 = []
                }
            });
        }
    }
});

Ich nahm Kyles Plugin-Idee und erweiterte sie, um sie automatisch zu verpacken und zwei Argumente anzunehmen. Es hat anfangs nicht funktioniert, aber ich habe es mit ein paar Änderungen und Ergänzungen zum Code zum Laufen gebracht.

Um die Funktion aufzurufen, verwenden Sie einfach das übergeordnete Element dessen, was Sie umbrechen möchten, und legen Sie dann Ihre Argumente wie folgt fest.

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

Das erste Argument gibt an, wie viele Elemente Sie zusammenschließen möchten, und das zweite Argument ist der Elementtyp, den Sie umbrechen möchten.

Sie können die Klasse des Wrapping-Elements in der Hauptfunktion unter der Variablen ändern wrapClass.

PixelPrecision
quelle
0

Ich habe diese Antwort für eine andere Frage vorbereitet, die ein Duplikat dieser Frage war. Vielleicht ist meine Variante für jemanden nützlich:

Ich denke, die Lösung, um alle drei Elemente zu verpacken, ist:

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)

Ich habe den gleichen Code bei jsbin mit einigen Verbesserungen geschrieben: http://jsbin.com/necozu/17/ oder http://jsbin.com/necozu/16/

Chekit
quelle