假设我有一系列“项目”,如下所示:
<p class="item">Item 1</p>
<p class="item">Item 2</p>
<p class="item group">Item 3</p>
<p class="item group">Item 4</p>
<p class="item">Item 5</p>
我想循环遍历项目,并将包含div的任何具有'group'类的内容包装成这样的结果(分组项目始终紧挨着彼此):
这是我得到的剧本:
var group = [];
$('.item').each(function(i, item) {
if ($(item).hasClass('group')) {
group.push(item);
}
});
$(group).wrap('<div class="wrapper" />');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p class="item">Item 1</p>
<p class="item">Item 2</p>
<div class="wrapper">
<p class="item group">Item 3</p>
<p class="item group">Item 4</p>
</div>
<p class="item">Item 5</p>
包装div在数组中分别包围每个元素(这是有道理的)但我需要将所有元素包装在一起。有什么方法可以做到这一点吗?这是一个jsFiddle。
这个问题有一个更复杂的变化是可能的,这种情况下这些群体中有几个“集合”,每个集合都包含在他们自己的“群组”div
中。初始状态:
<p class="item">Item 1</p>
<p class="item">Item 2</p>
<p class="item group">Item 3</p>
<p class="item group">Item 4</p>
<p class="item">Item 5</p>
<p class="item group">Item 6</p>
<p class="item group">Item 7</p>
<p class="item group">Item 8</p>
<p class="item">Item 9</p>
期望状态:
<p class="item">Item 1</p>
<p class="item">Item 2</p>
<div class="wrapper">
<p class="item group">Item 3</p>
<p class="item group">Item 4</p>
</div>
<p class="item">Item 5</p>
<div class="wrapper">
<p class="item group">Item 6</p>
<p class="item group">Item 7</p>
<p class="item group">Item 8</p>
</div>
<p class="item">Item 9</p>
答案 0 :(得分:8)
请尝试使用wrapAll
方法:
$(".group").wrapAll("<div class='wrap' />");
DEMO: http://jsfiddle.net/LanMt/3/
要包装单独的.group
元素组,您可以使用以下内容:
$(".group").map(function() {
if (!$(this).prev().hasClass("group")) {
return $(this).nextUntil(":not(.group)").andSelf();
}
}).wrap("<div class='wrap' />");
DEMO: http://jsfiddle.net/LanMt/5/
上面的代码是在@Jon's answer的帮助下组装的。
答案 1 :(得分:5)
您可以使用.filter
和.map
的组合来获得所需的结果:
$(".item.group")
.filter(function() {
return !$(this).prev().is(".group");
})
.map(function() {
return $(this).nextUntil(":not(.group)").andSelf();
})
.wrap('<div class="wrap" />');
Example on JS Bin解决当前的JSFiddle问题。
方法.wrap
将每个项目嵌入到您选择的标记内的当前jQuery对象中。因此,如果要在同一个包装器中包含多个元素,则必须将这N个元素与jQuery对象匹配,然后创建另一个包含一个元素的jQuery对象:第一个jQuery对象。后一个对象应该传递给.wrap
。
所以我们需要做的是为每个组创建一个jQuery对象,然后将所有这些对象放入另一个“master”jQuery对象中。首先选择本身不在.group
兄弟之前的所有.group
元素:
$(".item.group")
.filter(function() {
return !$(this).prev().is(".group");
})
从每个这样的元素创建一个jQuery对象,其中包含该元素以及所有具有.group
的兄弟姐妹:
.map(function() {
return $(this).nextUntil(":not(.group)").andSelf();
})
生成的jQuery对象会自动放在“master”对象中,因为它们取代了我们使用.filter
在我们使用$(".item.group")
创建的jQuery对象中选择的裸元素。对.wrap
的最后一次打电话......将事情搞砸了。 :)
答案 2 :(得分:4)
使用wrapAll而不是wrap。
$(".group").wrapAll('<div class="wrap" />');
wrapAll的文档可以在 - http://api.jquery.com/wrapAll/
找到其他包装方法可在 - http://api.jquery.com/category/manipulation/dom-insertion-around/
找到编辑:
对于可以有多个组的复杂情况,我们可以使用wrapAll和$ .each实现它,如下所示 -
var group = [];
$(".item").each(
function(i, item) {
if ($(item).hasClass("group")) {
group.push(item);
}
else {
$(group).wrapAll('<div class="wrap" />');
group = [];
}
}
);