Filippo oretti
Filippo oretti

Reputation: 49873

jQuery find when user scrolled out an element

I have 2 divs:

<div id="div1"></div>
<div id="div2"></div>

I would like to add css({'position':'relative'}) to div2 ONLY when a user scrolls the page and div1 is no longer visible on the page. When div1 is visible again, I want to remove the css rule.

Can anyone help me?

Upvotes: 0

Views: 1106

Answers (3)

Nhu Trinh
Nhu Trinh

Reputation: 13986

You could try this code:

$(window).bind('scroll', function() {
if ($(document).scrollTop() >= $('#div1').offset().top - $(window).height()) {
    //Change css relative
}else{

}
});

You should play with that until you got a perfect result. Good luck

Upvotes: 2

kritzikratzi
kritzikratzi

Reputation: 20241

this is not perfect, but i've written you a quick plugin to take care of this: http://jsfiddle.net/m7ztR/1/

it can be used in two ways:

it gives you a new selector console.log( $( "#elem" ).is( ":inView" )? "visible":"invisible" );

you can also use this to get all visible elements, e.g. console.log( $( "p:inView" ).get() );

and something like an event-listener $( "#watchThisElement" ).visibilityChange( function( visible ){ if( visible ){ // do this ... } else{ // do that ... } } );

note: this is not complete for a bunch of reasons!!

  1. it only handles vertical scrolling
  2. it does not handle iframes (and might screw up horribly with nested scrolling)
  3. there is no unbind
  4. it might get slow if you watch a lot of elements
  5. does not take window resizing into account

it's something i quickly hacked up from similar code i had sitting around.

if the jsfiddle link ever dies, here's the actual code and markup:

html:

<div id="status">look at my background color!</div>

<div id="above">lots of space above ... </div>
<div id="trackMe">i'm being tracked!</div>
<div id="below">lots of space below ... </div>

css:

#status{
    position: fixed; 
    right: 0; 
    top: 0; 
    background-color: red; 
}

#above, #below{
    height: 800px; 
    background-color: yellow; 
}

javascript:

/**
 * jquery (in)visibility plugin ... 
 */
(function( $ ){
    var w = $( window ); 

    // add a custom ":inView" selector
    $.expr[':'].inView = function(obj){
        var $this = $(obj);
        var relY = $this.offset().top - w.scrollTop(); 
        return relY >= 0 && relY <= w.height(); 
    }; 

    $.fn.visibilityChange = function( fun ) {  
        return this.each(function() {
            var elem = $(this);
            var pVisible = elem.is( ":inView" ); 
            $( document ).scroll( function( e ){
                if( pVisible != elem.is( ":inView" ) ){
                    pVisible = !pVisible; 
                    fun( pVisible ); 
                }
            });
        });
    };
})( jQuery );



$( "#trackMe" ).visibilityChange( function( visible ){
    $( "#status" ).css( "background-color", visible? "green":"red" ); 
} );

Upvotes: 1

Bas Slagter
Bas Slagter

Reputation: 9929

I think you should do some tricks with window.onscroll, the window height and the heigt of div1. As in...do some code in the onscroll method...check for the window height, check for the height of div1, do some calculations on it and check if the div is out of sight...if true...remove the css.

Upvotes: 1

Related Questions