Create sticky nav css and jquery

I am working on sticky navigation for a website now and I am facing several problems when nav becomes position:fixed, it seems like it is jumping and it looks “awkward”, here is the fiddle of what I'm trying to do,

http://jsfiddle.net/DKtLR/

Ideally, the result will be a user scroll, and the navigator will not be in a fixed position until it is scrolled from the viewport, after which it will become fixed and return to view mode.

+3
source share
4 answers

Since you only want it to become fixed when it completely leaves the viewport, then insert it, just change the property top, and then leave it in sight. See this script for a working example.

UPDATE

This updated script should work better because it only applies behavior if it is not already applied, and completely removes dynamic styles when returning to the normal 'static' position.

Note that when scrolling back, flicker still flashes - this is because nav “jumps” from its fixed position back to its static position. This can easily be solved using a similar method for the animation above.

+2
source

. setInterval (. ).

var interval_id = false;
var curOffset, oldOffset;
var altmenu;
$(document).ready(function(){
    altmenu = $('.top-nav')[0].cloneNode(true);
    altmenu.style.position = 'absolute';
    altmenu.style.display = 'none';
    document.body.appendChild(altmenu);
    oldOffset = $(window).scrollTop();
    $(document).bind('scroll',function(){
        if (interval_id) {
            return;
        }
        //altmenu.style.display = 'none'; // optional
        interval_id = setInterval(function() {
            curOffset = $(window).scrollTop();
            if(curOffset == oldOffset) {
                console.log('scrolling stopped',curOffset);
                clearInterval(interval_id);
                interval_id = false;
                if (curOffset>120) {
                    altmenu.style.display = 'block';
                } else {
                    altmenu.style.display = 'none';
                }
                $(altmenu).css({
                    top: (curOffset-120)+'px'
                }).animate({
                    top: (curOffset)+'px'
                }, 500);
            }
            oldOffset = curOffset;
        }, 500); //setInterval
    });//scroll
});//ready

script jsfiddle .

0

, ,

, , , , - , , .

HTML ():

<div id="menu">
    <ul>
        <li><a href="#">Home</a></li>
        <li><a href="#">About</a></li>
        ...
    </ul>
</div>
<div id="content" />

CSS, , ( )

#menu {
    position: absolute;
    width: 100%;
}
#menu.out {
    position: fixed;
}
#menu ul {
    margin: 0;
    list-style: none;
}
#menu ul li {
    display: inline-block;
}

script, ( , - native getBoundingClientRect() , , , ):

$(function() {

    // save element references for faster execution
    var menu = $("#menu");
    var ul = menu.find("ul");
    var content = $("#content")[0];

    // get menu actual height
    var menuHeight = menu[0].getBoundingClientRect().bottom;

    // detect whether menu is scrolled out
    var inView= true;

    $(document).scroll(function(evt) {
        evt.preventDefault();

        var top = content.getBoundingClientRect().top;
        var nextInView = (top + menuHeight) > 0;

        // did state change so we have to change menu positioning
        if (inView ^ nextInView)
        {
            inView = nextInView;
            if (inView)
            {
                menu.removeClass("out");
            }
            else
            {
                menu.addClass("out");
                ul.hide().slideDown("fast");
            }
        }
    });

});

. slideDown() slide in, , , .

, , , .

0

All Articles