frenchie
frenchie

Reputation: 52047

Finding index of first visible child in jQuery

I have a function that finds the index of the first visible child. It works but I'm wondering if there's a faster/better way to do it:

var TheDiv = $('#' + TheDivID);
var CurrentIndex = 0;

TheDiv.children().each(function () {
    if ($(this).is(':visible')) {
        CurrentIndex = $(this).index();
        break;
    }
});

Thanks for your suggestions.

Upvotes: 1

Views: 4517

Answers (2)

lonesomeday
lonesomeday

Reputation: 238115

Rob W's answer is good, and probably the shortest way to write this code. However, it isn't necessarily the most efficient.

jQuery's custom selectors are slow. They're not a patch on native selectors that can use querySelectorAll. What's more, children(':visible') (or suchlike) will test every single element for visibility, even if that's not necessary for your application. For instance, if you have 300 children and the first is visible, you don't need to test the next 299, but this method will do so.

So actually the approach you suggested in your question may not be too far away from the ideal. It wouldn't work as it is (break doesn't work in a jQuery selection) and is is phenomenally slow, but I think it can be cleaned up...

TheDiv.children().each(function (i) {
    if (jQuery.expr[':'].visible(this)) {
        CurrentIndex = i;
        return false;
    }
});

This uses return false to break out of the each loop. It also uses jQuery's filters (in a completely unorthodox and undocumented way) to test for visibility. The confusing line is exactly equivalent to $(this).is(':visible') except far, far quicker.

Since this breaks out of the loop as soon as a visible element is found, it may well be quicker than the selector-string method.

Upvotes: 3

Rob W
Rob W

Reputation: 349252

If TheDiv does already exists, add the selector in the .children() method, and use .index() to get the index of the element:

TheDiv.children(':visible').index();

Otherwise, use:

CurrentIndex = $('#' + TheDivID + ' > :visible').index();

Upvotes: 5

Related Questions