Adrien Gorrell
Adrien Gorrell

Reputation: 1319

jQuery : move an element on scroll, stop at some point, cross-browser compatible

I'm trying to have a fixed element on my page, that would follow the rest of the content up to a point when the user scrolls.

Try http://jsfiddle.net/sVzfx/1/ on internet explorer for instance and you will see my problem (which does not occur on firefox, and just does something a bit less weird on opera). In this jsfiddle I use the scroll event and a line of code to position the floating element :

$(window).scroll(function() {
    $("#floatingContent").css("top", Math.max(maxTopPosition, startingPoint - $(this).scrollTop()));
});

(see Stopping fixed position scrolling at a certain point? for this)

=> The scroll event takes place after the content was scrolled. Hence, the fixed element follows with some delay...

For a best user experience, it is vital that there is no such behaviour. My idea is to calculate the number of pixels that are being scrolled, position the element before the rest of the content is scrolled. The user wouldn't see that this element is positioned before the rest because its too quick, I think. Problem is, how do I do that ?!

I tried using mousewheel plugin (see http://brandonaaron.net/code/mousewheel/docs). It enables me to do something before the actual scroll, not to determine the number of pixels scrolled... (I thought deltaY parameter would return that, but it does not).

What would you do? x(

Maybe I should let the element relative and change it to fixed once it gets to the top of the page... Thus forget about moving it before scroll.

Upvotes: 1

Views: 4294

Answers (1)

Adrien Gorrell
Adrien Gorrell

Reputation: 1319

I came up with this solution after I got the idea of having a relative element as a basis instead of a fixed element. See http://jsfiddle.net/sVzfx/7/ :

var fixedElement = false;
var changingMoment = 250; // numbers of pixels from top where we want to fix or unfix
$(window).scroll(function() {
    // floatingContentMark lets us know where the element shall change 
    // from fixed to relative and vice versa
    var distanceFromTop = $("#floatingContentMark").offset().top - $(this).scrollTop();    
    if ((distanceFromTop <= changingMoment && !fixedElement) || 
        (distanceFromTop >= changingMoment && fixedElement)) 
    {    // either we came from top or bottom, same event triggered
         fixedElement = !fixedElement;
         $('#floatingContent').trigger('fixElement');
    }
});

// maybe dispatch in two different handlers, fix and unfix.
$('#floatingContent').bind('fixElement', function() {
    if ($(this).css('position') != 'fixed') {
        $(this).css('position', 'fixed') ;
        $(this).css('top', changingMoment ) ;
    }
    else {
        $(this).css('position', 'relative') ;
        $(this).css('top', 'auto') ;
    }
}) ;

Another solution could be http://imakewebthings.com/jquery-waypoints/shortcuts/sticky-elements/

Upvotes: 1

Related Questions