每3个div换一个div


85

是否可以使用nth-child选择器使用来包装3个div .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 2012年

Answers:


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'7

哇!感谢您的及时答复。几件事...所以,仅作澄清-使用nth-child不可能吗?&..作为一个完整的jQuery新手-如何使它起作用?我是否将其包装在jQuery(function($)...?中?)
csbourne

@csbourne-Nope:nth-child()对此不适合自己使用,就调用它而言,$(function() { });如果要在其上运行,请将其包装在a中document.ready,否则在运行时调用它:)
Nick Craver

感谢尼克的出色帮助和指导-效果很好。
csbourne 2010年

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" />');

包装程序的引号应采用正确的格式 <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');

当然,应将窗口替换为您的Handlers命名空间。

更新:更好地利用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 = []
                }
            });
        }
    }
});

我采用了Kyle的插件想法,并将其扩展为自动包装并接受两个参数。一开始它对我没有用,但是我通过对代码的一些编辑和添加使它开始运行。

要调用该函数,只需使用要包装的父元素,然后按如下所示设置参数即可。

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

第一个参数是要包装的元素数,第二个参数是要包装的元素类型。

您可以在main函数的变量下更改包装元素的类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/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.