0

I am trying to select all following elements of an element I choose. They don't necessarily have to be direct siblings of my chosen Element, so .nextAll() won't work.

Here's an example:

<div class="scope">
    <div> <a href="1">1</a> </div>
    <div> <a href="2">2</a> </div>
    <div> <a href="3">3</a> </div>
    <div> <a href="4">4</a> </div>
</div>

<a href="x">NOT THIS</a>

My element is a[href="2"], so I want to select a[href="3"] and a[href="4"], but not a[href="x"] because it's not in my scope.

I found this, but it only fetches one follower, but I need all of them.

I just wrote this, which works great, but it seems odd to me and I am sure that there have to be better solutions than this one:

var $two = $('a[href="2"]');

var selection = [];

var comes_after_2 = false;
$two.closest('.scope').find('a').each(function(){
    console.log(this, $two.get(0));
    if(comes_after_2){
        selection.push(this);
    }
    if(this == $two.get(0)){
        comes_after_2 = true;
    }
});

$(selection).css('background', 'red');

Here is a Fiddle to test it: http://jsfiddle.net/mnff40fy/1/

Please feel free to modify it, if there's a better solution. Thank you!

Community
  • 1
  • 1
YMMD
  • 3,730
  • 2
  • 32
  • 43
  • 1
    You said they don't have to be siblings, but they are in your example. Can you show an example where they're not siblings? – Barmar Aug 08 '14 at 20:09
  • I can't control the nesting of the elements, it is arbitrary. There will be just imagine that `a[href="2"]` could be nested more than the rest. – YMMD Aug 08 '14 at 22:52
  • I was just asking for a better example, to show the different cases, as I wasn't sure that I understood you. – Barmar Aug 08 '14 at 22:53
  • But you got me right. :) Anyway - here is an example: http://jsfiddle.net/mnff40fy/4/ With "not being siblings" I meant that they not necessarily have to be on the same level in the DOM-tree. – YMMD Aug 08 '14 at 22:58

3 Answers3

3
var $all_a = $two.closest('.scope').find('a');
// Get the position of the selected element within the set
var a_index = $all_a.index($two);
// Select all the remaining elements in the set
var $followers = $all_a.slice(a_index+1);
$followers.css('background', 'red');

DEMO

Barmar
  • 741,623
  • 53
  • 500
  • 612
1

How about this?

JSFiddle

I changed the markup a little to have the href='#' so you could click each one and see how the other elements respond.

$('a').click(function(){
    $('a').css('background', 'none');    
    var scopeDiv = $(this).closest('div.scope');
    var thisIndex = $(scopeDiv).find('a').index(this);
    $(scopeDiv).find('a').not(this).each(function(index){
       if(index >= thisIndex)
           $(this).css('background', 'red');    
    });
});
sbonkosky
  • 2,537
  • 1
  • 22
  • 31
0

As an alternative, you can use .nextAll() if you modify it a bit.

In your html code, you placed the a elements as children of the div tags. In order to incorporate .nextAll() you should select for the wrapper div elements and then call .nextAll() and then select for the children a elements.

Here is what I mean.

html

<div class="scope">
    <div>
        <a href="1">1</a>
    </div>

    <!-- Start Here -->
    <div class="start">
        <a href="2">2</a>
    </div>
    <div>
       <a href="3">3</a>
    </div>
    <div>
       <a href="4">4</a>
    </div>
</div>

<a href="x">NOT THIS</a>

js

$( '.start' ).nextAll().children( 'a' ).css( 'background-color', 'red' );

Explanation:

  • I select the wrapper div with $( '.start' )
  • I then select all of its subsequent siblings with .nextAll()
  • Of those siblings, I select their children that match 'a'
  • I apply the css

And here is the Fiddle

MSD
  • 544
  • 4
  • 24
  • This won't work, because I only have given a reference to `a[href="2"]`. I can't control if my "start" is nested deeper or as a parent of my wanted selection, sorry! – YMMD Aug 08 '14 at 22:54