BentCoder
BentCoder

Reputation: 12730

Static and Sticky fixed header transition misfunction

I created a sticky header based on scroll even but there are two problems:

  1. When scrolling up and down, there is jump at background. (I hope you understand what I mean)
  2. Sometimes both header divs appear together.

How can I solve the problem?

Thanks in advance

JSFiddle Demo

CSS:

*
{
    margin: 0;
    padding: 0;
}
#header, #page, #footer
{
    float: left;
    display: block;
    width: 100%;
}
#header
{
    background: #CCCCCC;
}
#default
{
    display: block;
    height: 100px;
    background: #64D989;
}
#sticky
{
    display: none;
    height: 50px;
    background: #D9D164;
}
#footer
{
    background: #EEEEEE;
}

JS:

$(document).ready(function()
{
    $(window).bind("scroll", function(e)
    {
        if ($(document).scrollTop() > 100)
        { 
            $("#header").css('position', 'fixed');
            $("#default").css('display', 'none');
            $("#sticky").css('display', 'block');
        }
        else
        {
            $("#header").css('position', 'relative');
            $("#sticky").css('display', 'none');
            $("#default").css('display', 'block');
        }
    });
});

HTML:

<div id="header">
    <div id="default">I AM DEFAULT HEADER</div>
    <div id="sticky">I APPEAR IF SCROLL POSITION > 100px</div>
</div>

<div id="page">
        START<br /><br />
        CONTENT<br /><br /><br />
        CONTENT<br /><br /><br />
        CONTENT<br /><br /><br />
        CONTENT<br /><br /><br />
        CONTENT<br /><br /><br />
        CONTENT<br /><br /><br />
        CONTENT<br /><br /><br />
        CONTENT<br /><br /><br />
        CONTENT<br /><br /><br />
        CONTENT<br /><br /><br />
        CONTENT<br /><br /><br />
        CONTENT<br /><br /><br />
        CONTENT<br /><br /><br />
        CONTENT<br /><br /><br />
        CONTENT<br /><br /><br />
        CONTENT<br /><br /><br />
        CONTENT<br /><br /><br />
        CONTENT<br /><br /><br />
        END
</div>

<div id="footer">I AM PAGE FOOTER</div>

Upvotes: 2

Views: 1664

Answers (2)

colestrode
colestrode

Reputation: 10658

For the first problem: part of the flash you are seeing is due to the fact that the sticky header won't appear until the scroll position is > 100. Since the default header has a height of 100px, when the scroll position is exatly 100px neither header is showing.

You can fix this by changing if ($(document).scrollTop() > 100) to if ($(document).scrollTop() >= 100).

For the second issue of both divs showing at the same time, you'll need to stop the current animation before hiding the div. See below:

EDIT I've updated to address performance concerns using the techniques John Resig posted here: http://ejohn.org/blog/learning-from-twitter/ Note that this will introduce a 250ms delay, so there will be a slight delay when transitioning from the default header to the sticky header.

Working Demo

$(document).ready(function () {
    var sticky = $('#sticky'),
        defaultHeader = $('#default'),
        header = $('#header')
        defaultShowing = true,
        didScroll = false;

    $(window).on("scroll", function (e) {
        didScroll = true;
    });

    window.setInterval(function () {
        if(didScroll) {
            didScroll = false;
            var scrollTop = $(document).scrollTop();

            if (defaultShowing && scrollTop >= 100) {
                defaultShowing = false;
                header.css('position', 'fixed');
                defaultHeader.stop().hide();
                sticky.fadeIn(1000);
            } else if (!defaultShowing && scrollTop < 100) {
                defaultShowing = true;
                header.css('position', 'relative');
                sticky.stop().hide();
                defaultHeader.fadeIn(1000);
            }
        }
    }, 250);
});

Upvotes: 3

Mooseman
Mooseman

Reputation: 18891

Not sure what you mean by background, as all backgrounds in the CSS you show are solid.

Binding an event to scroll with jQuery's .on() can get slow on some browsers. Meaning that it won't fire as often as it should, delaying any function bound the the scroll event. Also, since you're taking 1000ms to fade in the div, that will make the delay seem longer.

Upvotes: 2

Related Questions