36

I have a class of multiple 'DIV' elements and inside it are list of 'p' elements. See below:

<div class="container">
    <p>This is content 1</p>
    <p>This is content 2</p>
    <p>This is content 3</p>
</div>
<div class="container">
    <p>This is content 1</p>
    <p>This is content 2</p>
    <p>This is content 3</p>
</div>

Here's my jQuery code on calling the 'p' elements through hover:

$('.container').children('p').hover(function(){
    //get the nth child of p from parent class 'container'
});

How can I get the nth child number of the element 'p' from its parent container class 'container'?

Like if you hover

This is content 1

it should trigger output as 1;

TylerH
  • 20,799
  • 66
  • 75
  • 101
PHP Noob
  • 1,597
  • 3
  • 24
  • 34

3 Answers3

85

You can use jQuery's index function for that. It tells you where the given element is relative to its siblings:

var index = $(this).index();

Live example | source

The indexes are 0-based, so if you're looking for a 1-based index (e.g., where the first one is 1 rather than 0), just add one to it:

var index = $(this).index() + 1;

If you're not using jQuery and came across this question and answer (the OP was using jQuery), this is also quite simple to do without it. nth-child only considers elements, so:

function findChildIndex(node) {
    var index = 1;                         // nth-child starts with 1 = first child
    // (You could argue that you should throw an exception here if the
    // `node` passed in is not an element [e.g., is a text node etc.]
    // or null.)
    while (node.previousSibling) {
        node = node.previousSibling;
        if (node && node.nodeType === 1) { // 1 = element
            ++index;
        }
    }
    return index;
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
8

Use the parameter-less version of the .index() method to find the position of the element relative to its siblings:

$('.container').children('p').hover(function() {
     var index = $(this).index() + 1;
});

Note that the result of .index() will be zero-based, not one-based, hence the + 1

Alnitak
  • 334,560
  • 70
  • 407
  • 495
0
$('.container').children('p').hover(function(){
    //get the nth child of p from parent class 'container'
    var n = 1;
    var child = $(this).parent().find("p:eq("+n+")");
});

Should work!

Or if you want to know the index of the hovered element:

$('.container').children('p').each(function(index,element) {
    // use closure to retain index
    $(element).hover(function(index){
        return function() { alert(index); }
    }(index);
}

See http://api.jquery.com/each/

Willem Mulder
  • 12,974
  • 3
  • 37
  • 62
  • 1
    Yes it probably is. I didn't know about .index(). It doesn't really make a difference in performance either: http://jsperf.com/index-vs-each. So I learned something today :-) – Willem Mulder May 11 '12 at 12:03
  • 1
    it's not just performance, it's memory efficiency. Your version creates a new closure for every single matching element on the page. – Alnitak May 11 '12 at 12:20
  • 2
    I know, but it might be efficient if you want to store the index somewhere and .index() did not exist. Another option would be to store the index on the element itself. But it doesn't really matter: my option is certainly not optimal :-) – Willem Mulder May 11 '12 at 20:01