How to get the last visible element in jQuery?

advertisements

Please take a look at this:

http://jsfiddle.net/SHfz4/

Technically all those blue boxes are visible as in none are displayed as none so I can't use something like this:

$('.row .inner .item:visible:last');

Because that will give box 27 each time.

As you can see some boxes are visible and other's are not depending on the size of your view port, resizing will cause more boxes to go out of view or come into view.

I need a way to get the last visible item in a row. How to do this?

P.S. I have been snippets posted here on SO that show how to tell if an element is in view but some of those scripts were returning true even when they shouldn't and all of them required a specific element to be checked against, but my case requires me to just ask for the last and not specifically test a given element.

CSS:

.row { border: 1px solid red; height: 50px; overflow: hidden; }
.row .inner { width: 1000px; }
.row .inner .item { box-shadow: inset 0 0 8px blue; width: 50px; height: 50px; float: left; line-height: 50px; }

HTML:

<div class="row">
    <div class="inner">
        <div class="item item-1">1</div>
        <div class="item item-2">2</div>
        <div class="item item-3">3</div>
        <div class="item item-4">4</div>
        <div class="item item-5">5</div>
        <div class="item item-6">6</div>
        <div class="item item-7">7</div>
        <div class="item item-8">8</div>
        <div class="item item-9">9</div>
        <div class="item item-10">10</div>
        <div class="item item-11">11</div>
        <div class="item item-12">12</div>
        <div class="item item-13">13</div>
        <div class="item item-14">14</div>
        <div class="item item-15">15</div>
        <div class="item item-16">16</div>
        <div class="item item-17">17</div>
        <div class="item item-18">18</div>
        <div class="item item-19">19</div>
        <div class="item item-20">20</div>
        <div class="item item-21">21</div>
        <div class="item item-22">22</div>
        <div class="item item-23">23</div>
        <div class="item item-24">24</div>
        <div class="item item-25">25</div>
        <div class="item item-26">26</div>
        <div class="item item-27">27</div>
    </div>
</div>


Does this snippet do what you expect?

var items = document.querySelectorAll('div[class^=item]')
    ,row = items[0].offsetParent
    ,rightBoundary = row.clientLeft+row.clientWidth
    ,bottomBoundary = row.clientTop+row.clientHeight
    ,found = null;

for (var i=0;i<items.length;i+=1){
    if (items[i].offsetLeft > rightBoundary ||
        items[i].offsetTop > bottomBoundary){
        found = items[i-1];
        break;
    }
}
// reports div.item item-17

See this fork of your jsFiddle

[edit] added a check for [invisible] items below the first row of items, see the full screen version of the jsFiddle