开发者

jQuery to get next match in the DOM after a particular element

开发者 https://www.devze.com 2023-01-15 19:02 出处:网络
I hate to admit it but I\'m stuck trying to figure out how to do this. e.g. pretending you have the following structure:

I hate to admit it but I'm stuck trying to figure out how to do this.

e.g. pretending you have the following structure:

<div>
  ...
  <div>
    <ul>
      <li>
        <a href="..."><img class="foo"/></a><!-- "previous" -->
      </li>
      <li>
        <a href="..."><img class="bar"/></a>
      </li>
      <li>
        <a href="..."><img class="foo"/></a><!-- I'm at this node -->
      </li>
      <li>
        <a href="..."><img class="baz"/></a>
      </li>
      <li>
        <a href="..."><img class="foo"/></a><!-- "next" 1 -->
      </li>
    </ul>
  </div>
  ...
  <div>
    <ul>
      <li>
        <a href="..."><img clas开发者_Go百科s="foo"/></a><!-- "next" 2 -->
      </li>
      <li>
        <a href="..."><img class="baz"/></a>
      </li>
      <li>
        <a href="..."><img class="foo"/></a><!-- "next" 3 -->
      </li>
      <li>
        <a href="..."><img class="bar"/></a>
      </li>
    </ul>
  </div>
</div>

I'm in a jQuery event handler related to the highlighted "foo" node above. I want to find the "next" img element that is a "foo".

There's 2 problems though.

  1. I only want to select "foo" elements that are further in the DOM than the current node I'm at (e.g. the "previous" foo's, and the current foo are not desired)
  2. Although I've shown the nesting as a following a precise pattern, the generated code is/could be nested at any level... thus I can't just do .parent().parent().parent().siblings().find()... etc.

If you can imagine that every time the browser adds a node to the DOM it increments a counter and assigns the node that index... that you could retrieve... what I want is:

var here = $(this).getIndexInDOM();//e.g. returns 347
$('img.foo').each(function(){
  if($(this).getIndexInDOM() > here){//is this past our current index?
    doSomething($(this));//use it
    break;
  }
});

The .getIndexInDOM() method obviously doesn't exist in jQuery... but I'm curious if anyone has a solution to get the "next" element I'm after.

The only solution I can think of at the moment is really in-elegant and would perform pretty lousy when in the latter half of the images in the DOM...

//using vanilla JavaScript
var thisImg = theCurrentImageIHave;//some reference to the DOM element
var found = false;
for(var i=0;i<document.images.length;i++){
  if(found){
    if(document.images[i].className == 'foo'){
      doSomething(document.images[i]);
      break;
    }
  } else {
    if(document.images[i] == thisImg){
      found = true;
    }
  }
}


Inside the click handler, try this:

Example: http://jsfiddle.net/QVphP/ (click a blue box to add a border to the next one)

var $foo = $('img.foo');  // get all .foo images

var idx = $foo.index( this );  // get the index position of "this"
                               //    relative to all the .foo images found

var next = $foo.eq( idx + 1 ); // grab the .foo for the incremented index
  • http://api.jquery.com/index/
  • http://api.jquery.com/eq/


Check out next. It does exactly what you want.

$('img.foo').next().css('background-color', 'red');

If you'd like to get all the items after your currently selected item AND you know what position it is in your DOM, you can use the gt selector to select all the items "greater than" itself.

For example:

$('img.foo:gt(4)')

would give you back all of the items that are "greater than" the 4th item in the selection (AKA, after and not the current one).


Check out this jsfiddle. Click any image with a red border (foo) and the next red border (the next foo) will change to yellow.

Depending on how many foos you have in the page, this solution could be a bit of a performance hit. But since you aren't on 1.4 yet, this will work.

0

精彩评论

暂无评论...
验证码 换一张
取 消