2013-03-15 106 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