8

次のような「アイテム」のコレクションがあるとしましょう。

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

4

3 に答える 3

8

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の助けを借りて組み立てられました。

于 2012-06-28T10:16:35.313 に答える
5

.filterとの組み合わせを使用して.map、目的の結果を得ることができます。

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

実際に見てください

現在の JSFiddle の問題を回避するためのJS Bin の例。

根拠

このメソッドは、選択したマークアップ内の現在の jQuery オブジェクト内の各項目.wrapを埋め込みます。同じラッパーで複数の要素をラップする場合は、それらの N 個の要素を jQuery オブジェクトと一致させてから、1 つの要素 (最初の jQuery オブジェクト) を含む別の jQuery オブジェクトを作成する必要があります。に渡す必要があるのは、この後者のオブジェクトです。.wrap

したがって、ここで行う必要があるのは、グループごとに 1 つの jQuery オブジェクトを作成し、それらすべてを別の「マスター」jQuery オブジェクトに配置することです。兄弟.groupが先行していないすべての要素を選択することから始めます。.group

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

そのような各要素から、要素とそれに続くすべての兄弟を含む jQuery オブジェクトを作成します.group

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

.filter結果の jQuery オブジェクトは、で作成した jQuery オブジェクト内でで選択した裸の要素の代わりになるため、自動的に「マスター」オブジェクト内に配置され$(".item.group")ます。.wrap...への最後の呼び出しで、すべてが終了します。:)

于 2012-06-28T10:24:25.623 に答える
4

wrapの代わりにwrapAllを使用します。

$(".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-06-28T10:22:02.893 に答える