tags:

views:

118

answers:

5

A similar question was asked before, but I'm looking for a jQuery solution using only the html below (ie. no classes or id attributes):

<h2>Foo</h2>
<p>asdf</p>
<ul><li>asdf</li></ul>
<p>asdf</p>
<h2>Bar</h2>
<p>asdf</p>
<p>asdf</p>
<h2>Baz</h2>
<p>asdf</p>
<p>asdf</p>

I'd like to use some jQuery like:

$('h2').afterButBeforeNext('h2').doSomething();

This should:

  • select all the sibling elements after the specified element, but before the next occurrence of the specified element.
  • if there is no end element, then select all the elements underneath it.
A: 

How about this?

function selectBetween(node1,node2,parent)
{
    var p = $(parent);
    var n1 = p.find(node1);
    var n2 = p.find(node2);
    var results = [];
    var start = false;
    var end = false;
    p.children().each(function()
    {
     if(!start && !end)
     {
      if($(this) === n1)
      {
       start = true;
      }
      results.push(this);
      if($(this) === n2)
      {
       end = true;
       return;
      }
     }
    });
    return results;
}
var between = selectBetween($(parent).find('h2:first'), $(parent).find('h2:last'), parent);
Skawful
+5  A: 

The prev selector should be able to do this: http://docs.jquery.com/Selectors/siblings#prevsiblings

$("h2 ~ *:not(h2)").doSomething();

You still need some sort of id or attribute to select just one single h2 element.

markmywords
+1 But use `$("h2 ~ *:not(h2)")` instead.
Gumbo
Yes, I added it to my answer. Thank you!
markmywords
Nicely done, markmywords.
micahwittman
A: 

To demonstrate, the h2 tag content turns red and the p, ul tag content turns green:

$('#container').children().each(function(){
    if(this.nodeName == 'H2'){
        $(this).css('color','red');
        $(this).nextAll().each(function(){
            if(this.nodeName != 'H2'){
                $(this).css('color','green');
            }
        });        
        return false; //exit here to only process the nodes between the first H2 and second H2 found.
    }
});

Note that I'm assuming a #container div not shown in your example. If there is no container use $(body).children().

micahwittman
Not as simple as I was looking for, but works! Thx.
Beau Smith
No problem, and you're right. I upvoted the accepted answer - it was well deserved.
micahwittman
A: 

You can do something like this:

var name = "h2";
$(name).each(function() {
    var siblings = [], sibling=this.nextSibling;
    while (sibling && sibling.nodeName.toLowerCase() != name) {
        siblings.push(sibling);
        sibling = sibling.nextSibling;
    }
    // siblings now contains an array of sibling elements that are not h2
});
Gumbo
+1  A: 

Simplest solution using core jQuery functions:

$('h2').nextUntil('h2').doSomething();

Jonathan Snook pointed me to the jQuery 1.4 function that solves this:

Check out it's sibling functions:

Inspired by:

Beau Smith