10

I've got the jQuery .slideUp and .slideDown function below, and when reaching the #showfootershop div at the bottom of the browser window, the #footershop div slides up and then immediately slidesdown.

How can I get the #footershop to remain "up" and visible when #showfootershop is at the bottom of the browser window and not slide down until the user scrolls the browser window up?

Fiddle: http://jsfiddle.net/8PUa9/1/

jQuery:

$(window).scroll(function(){
/* when reaching the element with id "showfootershop" we want to
show the slidebox. */

    var distanceTop = $('#showfootershop').offset().top - $(window).height();

    if  ($(window).scrollTop() > distanceTop)
        $("#footershop").slideUp();
    else
        $("#footershop").slideDown();

});

html in footer:

<div id="showfootershop"></div>
<div id="footershop">
    <h1>Shop Links</h1>
</div>
</body>
</html>

CSS:

#footershop {
   height:35px;
   width:100%;
   display: none;
   z-index: 2;
}
Musa
  • 96,336
  • 17
  • 118
  • 137
markratledge
  • 17,322
  • 12
  • 60
  • 106
  • If you wish to have the footer div remain in the bottom, consider using `position`.http://jqueryui.com/position/ – Roger Ng Dec 04 '12 at 04:30
  • offset of a hidden element is `[0,0]` so the instant footer is hidden `dsitanceTop` is negative – charlietfl Dec 04 '12 at 04:51

6 Answers6

2

Use two functions for slidingUp and slidingDown, and toggle them once you have shown the slider and hidden it alternatively.

$(function() {

    var slideUp = function() {
        if ($(window).scrollTop() + $(window).height() >= $(document).height()) {
            console.log('At bottom!!');
            //toggle the handlers
            $("#footershop").slideDown(function() {
                $(window).off('scroll', slideUp).on('scroll', slideDown);
            });
        }
    };

    var slideDown = function() {
        if ($(window).scrollTop() + $(window).height() < $(document).height()) {
            //toggle the handlers
            $("#footershop").slideUp(function() {
                $(window).off('scroll', slideDown).on('scroll', slideUp);
            });
        }
    };


    $(window).on('scroll', slideUp);
});​

EDIT: I think the main problem you have is #footershop increases document.height when it shows and reduces when hidden, which is correct. This causes additional scroll events which creates the undesired behaviour.

Check this fiddle: I fixed this partially.

http://jsfiddle.net/BuddhiP/8PUa9/8/

Check this JSBin version for fixed version: http://jsbin.com/axobow/2

Main thing I did was #footershop is now absolutely positioned, so it doesn't cause the document size to change when shown or hidden, which is important in this case as if document.height() changed it affects you calculation.

Although fiddle works as expected, div is not positioned right on bottom. I hope you can fix that.

Hope this helps.

NOTE: You need to test the fiddle with full-height window, otherwise you will not see the footer sliding up since it shows somewhere in the middle of text.

BuddhiP
  • 6,231
  • 5
  • 36
  • 56
  • Hmm, getting closer. But on my test site, the footer appears in the middle of the window, and not consistently. This is harder to do than I thought! – markratledge Dec 04 '12 at 15:09
  • Yeah, so did in my fiddle too. But did not try to solve it as I thought its a matter of styling. I will have another look. – BuddhiP Dec 05 '12 at 01:25
  • @songdogtech, I've made a JSBin which works properly, please review and see if that's what you want. – BuddhiP Dec 09 '12 at 03:41
2

I'm not sure what's wrong with the other answers that you haven't accepted, but here's mine:

JSFiddle

JS:

$(window).scroll(function() {

    var distanceTop = $('#showfootershop').offset().top - $(window).height();

    if ($(window).scrollTop() >= distanceTop - 20) {
        $("#footershop").animate({
            'height': '35px'
        }, 'fast');
    }
    else {
        $("#footershop").animate({
            'height': '0px'
        }, 'fast');
    }
});​

CSS:

#footershop {
    height:0px;
    width:100%;
    z-index: 2;
    background:#00ffff;
    position: absolute;
    bottom:0;
    left:0;
    overflow:hidden;
}
body {
    position:relative;   
}

Belladonna
  • 3,824
  • 2
  • 24
  • 33
  • That works fine; I didn't check back in at these answers until now. Have to give the bounty to the earliest answer. – markratledge Dec 13 '12 at 03:24
1

An alternative to all of this jQuery slideUp/slideDown is to use CSS to handle it.

We detect when the user has reached your #showfootershop element and then add or remove a class from the footer:

$(window).scroll(function()
{

    var distanceTop = $('#showfootershop').offset().top - $(window).height();

    if($(document).scrollTop() >= distanceTop)
         $('#footershop').addClass("show");
    else
         $('#footershop').removeClass("show");
}

Then we use CSS to display the footer or hide it depending on the presence of that class:

#footershop 
{
    position: fixed;
    height: 0px;
    z-index:999;
    bottom: 0;
    overflow:none;
    
   -moz-transition:all 0.5s ease-in-out;
   -o-transition:all 0.5s ease-in-out;
   transition:all 0.5s ease-in-out;
   -webkit-transition:all 0.5s ease-in-out;
}
#footershop.show
{
    height:35px;
    
   -moz-transition:all 0.5s ease-in-out;
   -o-transition:all 0.5s ease-in-out;
   transition:all 0.5s ease-in-out;
   -webkit-transition:all 0.5s ease-in-out;
}

As you can see above when the .show class is on the footer we change the height of the footer element to display it. CSS transitions are then used to animate this change.

The nice thing about this method is it's very lightweight and efficient (especially if you've got a lot of jQuery animations working at the same time), and you can easily animate various different changes like the opacity, text and background colours, etc. without needing to touch your JS at all.

jsFiddle

Here's your jsFiddle modified http://jsfiddle.net/DigitalBiscuits/8PUa9/29/

Community
  • 1
  • 1
OACDesigns
  • 2,279
  • 14
  • 24
  • Thanks! This is more elegant than BuddhiP's code, and I will use it, but I have to give the bounty to him/her and they were earlier with the answer. cheers, mark – markratledge Dec 13 '12 at 03:18
  • I'm glad you found this method useful. It's a shame you chose the other answer as the correct answer though. Not so much because of the bounty, but more so because if others come here to find a solution for their own issue they're going to miss this answer and use BuddhiP's instead....which unfortunately is still buggy. – OACDesigns Dec 13 '12 at 10:49
0

slideUp() will also hide the element and offset of a hidden element is [0,0] so the instant footer is hidden distanceTop is negative. You could animate height to zero and get same visual result and since you aren't hiding the footer it will still have same top offset

charlietfl
  • 170,828
  • 13
  • 121
  • 150
0

I would recommend just putting a little buffer inbetween your scroll up and scroll down code.

I have made a slight tweak to your code to put in a buffer of 100px:

Javascript

$(window).scroll(function() {

    var distanceTop = $('#showfootershop').offset().top - $(window).height();

    if ($(window).scrollTop() >= distanceTop) {
        $("#footershop").slideDown();
    }
    else if ($(window).scrollTop() < (distanceTop - 100)) {
        $("#footershop").slideUp();
    }
});

Demo

3dgoo
  • 15,716
  • 6
  • 46
  • 58
0

Trying to scroll to an element is way too messy, just use the bottom of the page.

$(window).scroll(function() {
    if ($(window).scrollTop() + $(window).height() == $(document).height()) {
        $("#footershop").slideDown();
    }
    else {
        $("#footershop").slideUp();
    }
});​

jsfiddle

bobthyasian
  • 933
  • 5
  • 17