2013-03-15 91 views
4

我有一個cms,允許用戶在頁面上插入內容塊。用戶可以使用不同類型的內容塊,並且可以按任何順序插入。一個例子高層DOM結構可能是這個樣子:相鄰元素的jquery包裝組

<p>Some rich text</p> 

<div class="box">...</div> 
<div class="box">...</div> 
<div class="box">...</div> 

<h3>Some more rich text</h3> 
<p>Lorem ipsum</p> 

<div class="box">...</div> 
<div class="box">...</div> 

我想要做的就是包裝任何相鄰的「盒子」的div中包裝「容器」股利。所以在上面的例子中會有因爲有框的div兩個組的兩個「容器」 div的插入,導致:

<p>Some rich text</p> 

<div class="container"> 
    <div class="box">...</div> 
    <div class="box">...</div> 
    <div class="box">...</div> 
</div> 

<h3>Some more rich text</h3> 
<p>Lorem ipsum</p> 

<div class="container"> 
    <div class="box">...</div> 
    <div class="box">...</div> 
</div> 

我不認爲這是一個聰明的辦法用CSS選擇這樣做,所以有人知道無論如何用jQuery做到這一點?

+0

後期望的結果。你有嘗試過什麼嗎? – iappwebdev 2013-03-15 11:13:39

回答

3

那麼你可以這樣做JSFiddle example我剛剛掀起了。

這基本上循環遍歷每個.box它添加到一個數組並確定下一元件是否也具有.box類:

var collection = []; 
$('.box').each(function() { 
    var nextBox = $(this).next().hasClass('box'); 
    ... 
    collection.push($(this)); 
}) 

如果下一個元素具有.box類,它創建包含分隔線,在collection陣列所在的第一個.box之前將其放在頁面上,然後使用appendTo將所有.box分隔線移入其中:

if(!nextBox) 
    { 
     var container = $('<div class="collection"></div>'); 
     container.insertBefore(collection[0]); 
     for(i=0;i<collection.length;i++) 
     { 
      collection[i].appendTo(container); 
     } 
     collection = []; 
    } 
+0

對我而言,這是最穩健的解決方案。 – benb 2013-03-15 13:05:43

2

的小提琴是在這裏:http://jsfiddle.net/jdelight/XutA6/5/ 這裏是一個可能的解決方案使用CSS,它可以讓你用一個單一的背景顏色和邊框樣式塊。 HTML代碼將是這樣的:

<div class="block">this is block 1</div> 
    <div class="block">this is block 2</div> 
    <div class="block">this is block 3</div> 
    <div class="block">this is block 4</div> 
    <div class="block">this is block 5</div> 

而CSS將是:

  /* style all blocks with the required background colour and border */ 
     .block { 
      background: #eee; 
      color: #000; 
      border: 1px solid red; 
      border-bottom: 0; 
      padding: 20px; 
      width: 400px; 
      border-radius: 20px; 
      /* remove the rounded corners from he bottom left/right */ 
      border-bottom-left-radius:0; 
      border-bottom-right-radius:0; 
      position: relative; 
     } 
     /* style all adjacent blocks and remove the radius - so the top block has a radius and the others don't */ 
     .block + .block { 
      border-radius: 0; 
      border-top: 0; 
     } 

     /* create a cheeky block with content after which sits below all blocks */ 
     /* so it's hidden from all the blocks above it apart from the very bottom one (see bottom: -10px) */ 
     /* then style the rounded corners on that one */ 
     .block::after { 
      content:'.'; 
      display: block; 
      background: red; 
      height: 10px; 
      position: absolute; 
      border-bottom: 1px solid red; 
      border-left: 1px solid red; 
      border-right: 1px solid red; 
      bottom: -10px; 
      width: 440px; 
      background: #eee; 
      left:-1px; 
      border-bottom-left-radius:10px; 
      border-bottom-right-radius:10px; 
     } 
+0

讓我的答案慚愧!做得好! – 2013-03-15 12:12:27

+0

這幾乎就在那裏,但我最終無法使用它,因爲絕對定位意味着我會在底部重疊內容時遇到問題。 – benb 2013-03-15 12:34:22

2

您可以使用

  1. .nextUntil,讓所有的下一個.box
  2. .andSelf當前元素添加到集合
  3. .wrapAll纏繞每個收集到不同.container

$('.box').not('.box+.box').each(function(){ 
 
    $(this).nextUntil(':not(.box)').addBack().wrapAll('<div class="container" />'); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<p>Some rich text</p> 
 

 
<div class="box">...</div> 
 
<div class="box">...</div> 
 
<div class="box">...</div> 
 

 
<h3>Some more rich text</h3> 
 
<p>Lorem ipsum</p> 
 

 
<div class="box">...</div> 
 
<div class="box">...</div>

http://jsbin.com/gonino/edit?html,js

+1

完美,但'andSelf()'已棄用。現在是'addBack'。使用cheerio(Node的jQuery clone)來解決這個問題。 – Moss 2016-03-08 00:14:43

+0

......它也沒有'wrapAll',所以也許這對我來說畢竟不適用。 :(:P – Moss 2016-03-08 00:17:19

+0

謝謝。我試圖替換爲'.addBack()',它似乎工作正常。是不是? – 2016-03-08 08:57:04