Jquery ordering groups of adjacent elements

I have cms that allows users to embed content blocks on a page. Various types of content are available to the user, and they can be inserted in any order. An example of a high-level dom structure might look something like this:

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

What I want to do is wrap any adjacent β€œside” divs in a wrap container div. Thus, in the above example, two β€œcontainers” of divs would be added, since there are two div div groups, resulting in:

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

I don’t think there is an efficient way to do this with css selectors, so does anybody know about this with jQuery anyway?

+5
source share
3 answers

Ok, you could do it like JSFiddle Example I just hacked.

This basically goes through each .box , adding it to the array and determining if the following element has a .box class:

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

If the next element does not have the .box class, it creates the contained separator, places it on the page before the first .box is found in the collection array, and then uses appendTo to move all the .box separators .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 = []; } 
+4
source

you can use

  • .nextUntil to get all of the following .box .
  • .andSelf to add the current item to the collection
  • .wrapAll to wrap each collection in a different .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

+3
source

The fiddle is here: http://jsfiddle.net/jdelight/XutA6/5/ A solution using css is possible here, which allows you to create blocks with one background color and border. The HTML looks something like this:

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

And CSS will be:

  /* 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 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; } 
+2
source

Source: https://habr.com/ru/post/1469476/


All Articles