Оберніть кожні 3 div в div


85

Чи можна за допомогою nth-childселекторів обернути 3 divs, використовуючи .wrapAll? Здається, я не можу скласти правильне рівняння.

тому...

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

стає ...

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

2
gist.github.com/3181731 Гарний плагін jQuery, який робить саме це. Сподіваюся, вам це буде корисно.
iMoses

Відповіді:


179

Ви можете зробити це за допомогою .slice():

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

Ви можете спробувати демонстраційну версію тут , все, що ми робимо тут, - це отримати елементи, які ви хочете обернути, і прокрутити їх, зробити .wrapAll()партіями по 3, потім перейти до наступних 3 і т. Д. Це буде обертати 3 за раз і однак багато залишається в кінці, наприклад 3, 3, 3, 2, якщо це так.


Я б зробив це функцією і зробив аргументом кількість обгорнутих div. Щось на зразок applyDivGrouping (divs, divsPerGroup);
Stefan Kendall

Оце Так! Дякуємо за оперативну відповідь. Кілька речей ... Отже, лише для роз’яснення - це неможливо за допомогою nth-child? & .. Як повний початківець jQuery - як я можу це функціонувати? Чи я обертаю його у jQuery (функція ($) ...?) Велике спасибі
csbourne

@csbourne - Nope :nth-child()погано це робить, оскільки для виклику цього просто оберніть його в, $(function() { });якщо ви хочете його запустити document.ready, інакше зателефонуйте, коли ви хочете його запустити :)
Нік Кравер

Дякую Ніку за фантастичну допомогу та керівництво - працює чудово.
csbourne

3
@Fahad, згідно з логікою NickCraver, ти можеш просто відредагувати маленький фрагмент коду var divs = $("div > .classname");АБО var divs = $("div .classname");дякую

23

Я написав загальну функційну послідовність, яка робить це досить простим:

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


8

Плагін

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

Як ним користуватися.

Зателефонуйте EveryWhat()елементу та введіть число для кожного елемента, який ви хочете зібрати.

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

котирування wrapinner повинні мати належне форматування <div class="new" />за допомогою класу та закриваючого тегу. Stackoverflow заважає мені показувати, як це виглядає, але ось посилання на самозакриваючий div.

Як це повинно виглядати

Це оберне кожне інше число, яке ви вказали. Я використовую jquery 1.8.2. тому пам’ятайте, що EveryWhat(3)кожен раз використовуйте виклик селектора та номер. Звичайно, розмістивши його внизу сторінки або загорнувши в

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

Ви можете використовувати кожен n-й, а потім .wrapInner('<div class="new" />')для тих самих результатів.


1
Ви вже можете це зробити за допомогою, $('div > div:nth-child(3n)')а насправді не призводите до двох груп із трьох елементів.
Яцк,

7

Ось більш корисна версія Ніка вище:

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

Ви б використали це як:

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

вікно, звичайно, слід замінити на ваш простір імен.

Оновлено: Трохи краща версія, яка використовує 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);

Використовуйте як:

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

Другий параметр для назви обгортки необов’язковий.


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

Я взяв ідею плагіна Кайла і поширив його на автоматичне перенесення і взяв два аргументи. Для мене це не спрацювало, але я запустив його за допомогою декількох редагувань та доповнень до коду.

Для виклику функції просто використовуйте батьківський елемент того, що ви хочете обернути, а потім встановіть свої аргументи наступним чином.

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

Перший аргумент - це кількість елементів, які ви хочете обернути разом, а другий аргумент - тип елемента, який ви хочете обернути.

Ви можете змінити клас елемента обтікання в основній функції під змінною wrapClass.


0

Я підготував цю відповідь до іншого питання, яке повторювалось до цього. Тож, можливо, мій варіант буде корисним для якогось одного:

Я думаю, що рішення для обгортання всіх трьох елементів:

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)

Я написав той самий код у jsbin з деякими вдосконаленнями http://jsbin.com/necozu/17/ або http://jsbin.com/necozu/16/

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.