最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Creating a sticky nav css and jquery - Stack Overflow

programmeradmin3浏览0评论

I am working on a sticky nav for a website currently, and I am running into a few problems, when the nav bees position:fixed it seems to jump and it looks "clunky", here is a fiddle of what I am trying to do,

/

Ideally the oute would be the user scrolls and the nav is not in a fixed position until it is scrolled out of the viewport it then bees fixed and and slides back into view.

I am working on a sticky nav for a website currently, and I am running into a few problems, when the nav bees position:fixed it seems to jump and it looks "clunky", here is a fiddle of what I am trying to do,

http://jsfiddle/DKtLR/

Ideally the oute would be the user scrolls and the nav is not in a fixed position until it is scrolled out of the viewport it then bees fixed and and slides back into view.

Share Improve this question asked Jul 18, 2012 at 9:36 UddersUdders 7,00627 gold badges108 silver badges207 bronze badges 4
  • 2 how will this work in this example? the menu is already at the top of the page, there isn't any case where the user's viewport is above the menu. this will probably work better if the menu is not at the top of the page. – Rodik Commented Jul 18, 2012 at 9:40
  • I would also say: if it's already on top of the page leave it there and fix it right away. If it's not, scroll it until it hits the ceiling and than fix it. – insertusernamehere Commented Jul 18, 2012 at 9:47
  • Thats what I am trying to do, but it feels like there is a jump when it bees fixed – Udders Commented Jul 18, 2012 at 9:48
  • 1 You should take a look at this one. – morgi Commented Jul 18, 2012 at 9:48
Add a ment  | 

4 Answers 4

Reset to default 2

Since you only want it to bee fixed when it is pletely out of viewport, then slide in, just modify the top property and then animate it back into view. See this fiddle for a working example.

UPDATE

This updated fiddle should work better, as it only applies the behaviour if not already applied, and pletely removes dynamic styles when returning to normal 'static' position.

Note there is still a flicker when scrolling back up - this is because the nav 'jumps' from its fixed position back to its static position. This can easily be resolved using a similar technique to the animation above.

You can simply use the StickyScroller jquery plugin: http://vertstudios./blog/jquery-sticky-scroller-position-fixed-plugin/

At top and then fixed with animation so it's not clunky

This might be the solution you're looking for because it provides the fixed menu bar when scrolled out of the view, but when it switches from top to fixed, it does a slide-down animation, so it doesn't feel as you described it clunky.

HTML I've used in the example (simplified):

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

CSS is of course simple (only relevant styles)

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

And the script that does it and does so quickly (so it performs as fast as possible because the slowest part is the call to browser native getBoundingClientRect() function which means it's still fast, very fast):

$(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");
            }
        }
    });

});

And this is it. You could also tweak the animation from slideDown() to slide in by animating top style property while you know exactly how many pixels above the view port you have to put the menu before the animation.

When you scroll the page and menu gets out of the view, it switches it to fixed position and scrolls the menu down so it dosesn't just jump in view but rather smoothly gets back in.

I made this alternative solution based on this solution. Based on the setInterval function (see also console log).

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

Test script and jsfiddle are here.

发布评论

评论列表(0)

  1. 暂无评论