【问题标题】:Can I $.wrap() around a collection of elements in an array?我可以 $.wrap() 围绕数组中的元素集合吗?
【发布时间】:2012-06-28 10:14:14
【问题描述】:

假设我有一个这样的“项目”集合:

<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 以产生类似的结果(分组的项目将始终彼此相邻):

这是我得到的脚本:

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>

【问题讨论】:

  • 您只想对连续的.group 元素集进行分组吗?即你可以在一个列表中有两个组,需要分开吗?
  • @Alnitak,你怀疑我拿了你的东西是对的。这确实是正确的,可能有几组“组”要被包装。我会更新我的问题,但是是的,我正在摆弄 jsFiddle,而且速度非常慢......

标签: javascript jquery dom


【解决方案1】:

改用wrapAll 方法:

$(".group").wrapAll("<div class='wrap' />");

演示: http://jsfiddle.net/LanMt/3/


要包装单独的 .group 元素组,您可以使用以下内容:

$(".group").map(function() {
    if (!$(this).prev().hasClass("group")) {
        return $(this).nextUntil(":not(.group)").andSelf();
    }
}).wrap("<div class='wrap' />");

演示: http://jsfiddle.net/LanMt/5/

上面的代码是在@Jon's answer的帮助下组装的。

【讨论】:

  • VisioN,我将在我的代码中使用它,如果 CC 许可有任何问题,请提出异议。这非常简单,并且利用了我最初喜欢 jQuery 但在更多地学习 JavaScript 后偏离了...也就是说,将单个命令串在一起实现这么多的简单性!另外,我学习了两个新方法.andSelf().map() 方法来产生.wrapAll() 效果。
  • @AlexanderDixon 很高兴您发现这很有用。随意在任何你喜欢的地方使用代码。顺便说一句,考虑使用addBack 而不是andSelf,因为后者现在已被弃用。
【解决方案2】:

您可以使用.filter.map 的组合来达到预期的效果:

$(".item.group")
.filter(function() {
    return !$(this).prev().is(".group");
})
.map(function() {
    return $(this).nextUntil(":not(.group)").andSelf();
})
.wrap('<div class="wrap" />');

See it in action.

Example on JS Bin 解决当前的 JSFiddle 问题。

基本原理

.wrap 方法将 每个项目 嵌入到您选择的标记内的当前 jQuery 对象中。因此,如果你想在同一个包装器中包装多个元素,你必须将这 N 个元素与一个 jQuery 对象匹配,然后创建另一个包含 one 元素的 jQuery 对象:第一个 jQuery 对象。您应该将后一个对象传递给.wrap

所以我们需要在这里为每个组创建一个 jQuery 对象,然后将所有这些放入另一个“主”jQuery 对象中。首先选择所有前面没有.group 兄弟的.group 元素:

$(".item.group")
.filter(function() {
    return !$(this).prev().is(".group");
})

从每个这样的元素中,创建一个 jQuery 对象,其中包含该元素和所有以下带有.group 的兄弟元素:

.map(function() {
    return $(this).nextUntil(":not(.group)").andSelf();
})

生成的 jQuery 对象会自动放置在“主”对象中,因为它们取代了我们在使用 $(".item.group") 创建的 jQuery 对象中使用 .filter 选择的裸元素。最后打电话给.wrap... 结束了。 :)

【讨论】:

  • 花了大约 4 年的时间,但是,感谢您的 .wrap() 双关语。我得到了它!另外,感谢这个很棒的答案和解释。
【解决方案3】:

使用 wrapAll 代替 wrap。

$(".group").wrapAll('<div class="wrap" />');

wrapAll 的文档可以在 -http://api.jquery.com/wrapAll/ 找到

其他可用的包装方法可以在 -http://api.jquery.com/category/manipulation/dom-insertion-around/ 找到

编辑:

对于可能有多个组的复杂情况,我们可以使用带有 $.each 的 wrapAll 来实现,如下所示 -

var group = [];
        $(".item").each(
          function(i, item) {            
            if ($(item).hasClass("group")) {
                group.push(item);
            }
            else {
                $(group).wrapAll('<div class="wrap" />');
                group = [];
            }
          }
        );

【讨论】:

    猜你喜欢
    • 2012-01-21
    • 1970-01-01
    • 2018-10-17
    • 2012-12-20
    • 2020-11-27
    • 1970-01-01
    • 2011-06-08
    • 2016-06-20
    • 1970-01-01
    相关资源
    最近更新 更多