How can I wrap each element and all its siblings before the next occurrence of the same element?
Asked Answered
R

2

5

I've got some markup that's similar to the following:

<h3>A Heading</h3>
<p>Here is a paragraph.</p>

<ul>
  <li>First</li>
  <li>Second</li>
</ul>

<blockquote>Here's some other block-level element</blockquote>

<h3>The Wrapping Should Stop Before This Heading, but a Second One Should Begin</h3>
<ol>
  <li>First</li>
  <li>Second</li>
</ol>

<p>Notice the varying block-level elements? It probably doesn't make any difference.</p>

I want to wrap each h3 and everything up to, but not including, the next h3 in a single div.

The result should be:

<div>
  <h3>A Heading</h3>
  <p>Here is a paragraph.</p>

  <ul>
    <li>First</li>
    <li>Second</li>
  </ul>

  <blockquote>Here's some other block-level element</blockquote>
</div>

<div>
  <h3>The Wrapping Should Stop Before This Heading, but a Second One Should Begin</h3>
  <ol>
    <li>First</li>
    <li>Second</li>
  </ol>

  <p>Notice the varying block-level elements? It probably doesn't make any difference.</p>
</div>

I've found similar questions like this one. It uses a combination of .nextUntil() and .andSelf() (or .addBack() once my edit is approved), but this would wrap the h3s and the content between in separate divs.

Richella answered 8/9, 2013 at 5:1 Comment(0)
R
4

It seems .wrapAll() was the missing link.

$('h3').nextUntil('h3').addBack().wrapAll('<div>');
Richella answered 8/9, 2013 at 5:7 Comment(0)
B
3

You need the :first selector otherwise you will wrap all the content not just the first h3to 2nd h3

$('h3:first').nextUntil('h3').addBack().wrapAll('<div>');

Fiddle

Brokenhearted answered 8/9, 2013 at 5:9 Comment(1)
That's right. For my particular use case I was getting them all, but that wasn't stated in the question for simplicity's sake.Richella

© 2022 - 2024 — McMap. All rights reserved.