1

Take a look at this jsFiddle.

When you scroll down a bit, a navbar should appear on the left. This works as it should. The problem arises when you scroll back to the very top. It should hide immediately, but it does not. Sometimes it hides after some seconds of delay and sometimes it does nothing. It doesn't hide either when you press the 'to top' button, which it should.

Any thoughts?

HTML

<nav id="menu-float">
    <ul>
        <li>List item 1</li>
        <li>List item 2</li>
        <li>List item 3</li>
    </ul>
    <div id="toTop">to top</div>
</nav>

CSS

nav#menu-float {
    position: fixed;
    left: 50%;
    margin-left: -300px;
    width: 120px;
    background: white;
    padding: 0.2em 0.4em;
    padding-bottom: 10px;
    border-radius: 8px;
    box-shadow: 0 3px 0px rgba(0, 0, 0, 0.1);
    top: 0;
    opacity: 0;
}

nav#menu-float div#toTop {
    background: #ffffff;
    background: -moz-linear-gradient(top,  #ffffff 0%, #ededed 100%);
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff),   
color-stop(100%,#ededed));
    background: -webkit-linear-gradient(top,  #ffffff 0%,#ededed 100%);
    background: -o-linear-gradient(top,  #ffffff 0%,#ededed 100%);
    background: -ms-linear-gradient(top,  #ffffff 0%,#ededed 100%);
    background: linear-gradient(top,  #ffffff 0%,#ededed 100%);
    border: 1px #DDD solid;
    border-radius: 8px;
    box-shadow: 0 2px 2px rgba(0, 0, 0, 0.08);
    width: 50px;
    height: 20px;
    right: 5px;
    position: absolute;
    bottom: 5px;
    cursor: pointer;
    text-align: center;
}

JAVASCRIPT

// Only show side menu when x pixels from top and when window size allows it
function checkSize() {
    var floatMenu = $("nav#menu-float");

    if ($(window).width() > 560) {
            $(window).scroll(function() {
                if ($(document).scrollTop() > 100) {
                    floatMenu .animate({
                        opacity: 1,
                        top: "45px"
                    }, 800);
                }
                else {
                    floatMenu .animate({
                        opacity: 0,
                        top: "0px"
                    }, 800);
                }
            });
    }
    else {
        floatMenu .hide();
    }
}

checkSize();
$(window).resize(function() {
    checkSize();
});

// Back to top
$("div#toTop").click(function(e) {
    $("body,html").animate({
            scrollTop: 0
    }, 800);
});

2 Answers 2

2

This should work:

$(function() {
    "use strict";
    function checkSize() {
        if ( $(window).width() > 560 ) {
            $(window).scroll(function() {
                if ( $(document).scrollTop() > 100 ) {
                    if ( $("nav#menu-float").css("opacity") === "0" ) {
                        $("nav#menu-float").animate({
                            opacity: 1,
                            top    : "45px"
                        }, 800);
                    }

                }
                else {
                    if ( $("nav#menu-float").css("opacity") === "1" ) {
                        $("nav#menu-float").animate({
                            opacity: 0,
                            top    : "0px"
                        }, 800);
                    }
                }
            });
        }
        else {
            $("nav#menu-float").hide();
        }
    }

    $(window).resize(checkSize);
    checkSize();

    $("div#toTop").click(function() {
        $("body,html").animate({
            scrollTop: 0
        }, 800);
    });
});

You have to check if the animation is done, otherwise you're going to animate the element again, again and again. if ( $("nav#menu-float").css("opacity") === "0" ) { checks if the opacity animation is done.

DEMO

Sign up to request clarification or add additional context in comments.

5 Comments

What does that use strict do? This seems like the most logical answer indeed. Are sure that three = are needed when comparing with a natural number?
@BramVanroy Strict Mode is a new feature in ECMAScript 5 that allows you to place a program, or a function, in a "strict" operating context. This strict context prevents certain actions from being taken and throws more exceptions. Read more about use strict
@BramVanroy and about ===, I always use this because I do not want the type conversion that == does. 1 == "1" // true but 1 === "1" // false
I tried implementing this, but it's just too bad performance wise. Any thoughts? : bramvanroy.be
Never mind, I used a variable to make sure the dom needn't be searched all the time and it works fine now. Thanks again!
1

You're queuing up tons of animations every time the scroll event fires, adding another 800ms to the overall time. You need to set some sort of flag to stop the scroll events from firing when the menu is showing, and remove the flag when scrolling goes back to the top to allow the menu to hide again.

The following just adds a check to see if the menu has a class of 'showing' and toggles the class on and off accordingly:

function checkSize() {
    var floatMenu = $("nav#menu-float");

    if ($(window).width() > 560) {
            $(window).scroll(function() {
                if ($(document).scrollTop() > 100 && !floatMenu.hasClass('showing')) {
                    floatMenu.addClass('showing').animate({
                        opacity: 1,
                        top: "45px"
                    }, 800);
                }
                else if ($(document).scrollTop() < 100 && floatMenu.hasClass('showing')) {
                    floatMenu.removeClass('showing').animate({
                        opacity: 0,
                        top: "0px"
                    }, 800);
                }
            });
    }
    else {
        floatMenu .hide();
    }
}

SEE MY FORK HERE

1 Comment

I don't like adding classes too much, so I think I'll go with sQVe's solution. +1 for the effort though!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.