Giberno
Giberno

Reputation: 1323

jquery scroll in an element check scroll up/down, visible/not

I have some menu.

<ul>
    <li>item1</li>
    <li>item2</li>
    <li>item3</li>
    <li>item4</li>
    <li>item5</li>
    <li>item6</li>
    <li>item7</li>
    <li>item8</li>
    <li>item9</li>
    <li>item10</li>
    <li id="current">item11</li>
    <li>item12</li>
    <li>item13</li>
    <li>item14</li>
    <li>item15</li>
    <li>item16</li>
    <li>item17</li>
    <li>item18</li>
    <li>item19</li>
    <li>item20</li>
    <li>item21</li>
</ul>

ul could be scroll by mouse.

ul{width:100px;height:200px;overflow-x:hidden;overflow-y:auto}
li{float:left;overflow:hidden;width:100px;font:14px/24px arial;border-bottom:1px solid #ddd;}
#current{background:#ccc;}

Now I want to detect when #current is not visible, in the case mouse scroll up and mouse scroll down.

jQuery(document).ready(function(){
    var lastscrollposition = $('#current').scrollTop();
    $("ul").bind('scroll',function(){
        var currentscrollposition = $('#current').scrollTop();
        if(!$('#current').is(':visible')){
            if (currentscrollposition > lastscrollposition){           
               //fixed #current position on the top of the ul
            }else{
               //fixed #current position on the bottom of the ul
           }
       }
       lastscrollposition = currentscrollposition;
    });
});

But the jquery code not run, hope someone could help me, thanks.

online code in http://jsfiddle.net/UT7uU/

UPDATE Thanks to all. finally, the question is not such difficult as I thought first. It just make a judgment between $('#current').offset().top and $('ul').offset().top

jQuery(document).ready(function(){
    $("ul").bind('scroll',function(){
        if($('#current').offset().top<$('ul').offset().top) {         
               alert('aaa');//fixed #current position on the top of the ul
        }else if($('#current').offset().top>($('ul').offset().top+$('ul').height())) {   
               alert('bbb');//fixed #current position on the bottom of the ul
       }
    });
});

see demo in http://jsfiddle.net/UT7uU/14/

regards.

Upvotes: 0

Views: 762

Answers (2)

Joe Atzberger
Joe Atzberger

Reputation: 3306

The best way I have found to ask "is this actually on screen?" is the jQuery viewport extension:

http://www.appelsiini.net/projects/viewport

Making the code just:

if(!$('#current').is(':in-veiwport')){ ...

Or, more easily:

if($('#current').not(':in-veiwport')){ ...

Upvotes: 2

ondrc
ondrc

Reputation: 106

The :visible selector does not take scrollbars into account:

Elements are considered visible if they consume space in the document. Visible elements have a width or height that is greater than zero.

Elements with visibility: hidden or opacity: 0 are considered visible, since they still consume space in the layout.

Elements that are not in a document are considered to be hidden; jQuery does not have a way to know if they will be visible when appended to a document since it depends on the applicable styles.

...

(http://api.jquery.com/visible-selector/)

I bet you would have to do some manual work to find out whether the element is scrolled off. For exanple something like this:

function isCurrentInUlViewport() {
  var heightOfUl = $('ul').height();
  var positionOfCurrent = $('#current').position().top

  return positionOfCurrent < heightOfUl && positionOfCurrent > 0
}

The code snippet will require some further tweaking in order to get height of #current element into account. Also assumes that ul is offset parent of #current. See http://api.jquery.com/position/ for more details.

Upvotes: 1

Related Questions