Replacing A Sticky Header With A Second Header When It Reaches The Currently Stuck Header
Solution 1:
I believe that the following will do exactly as you want...
The #firstHeader
will bind to the top when scrolled past, and then when the #secondHeader
collides with the bottom of the #firstHheader
they will join and the #firstHeader
will be pushed off of the screen until the #secondHeader
reaches the top of the screen and binds there...
Hopefully that makes sense, if not, it'll probably be easier if you see it in action: http://jsfiddle.net/yZKea/
This solution does use jquery
. So you'll need to include a reference to it in your head
before the rest of the JS
code:
<scriptsrc="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
NOTE: The JS
isn't as daunting or as long as it looks, most of it is repeated setting of styles. You could easily change it to just a few lines :)
CSS
html, body {
margin: 0;
padding: 0;
border: 0;
}
.spacer{
height:200px;
background:#f00;
opacity:.5;
border-top:#d225px solid;
width: 100%;
}
#firstHeader{
background:#00f;
height: 100px;
width: 100%;
z-index:500;
}
#secondHeader{
background:#0f0;
height: 100px;
width: 100%;
z-index:500;
}
HTML
<body><divclass="spacer"></div><divid="firstHeader">Header 1</div><divclass="spacer"></div><divclass="spacer"></div><divclass="spacer"></div><divid="secondHeader">Header 2</div><divclass="spacer"></div><divclass="spacer"></div><divclass="spacer"></div><divclass="spacer"></div><divclass="spacer"></div><divclass="spacer"></div><divclass="spacer"></div><divclass="spacer"></div><divclass="spacer"></div><divclass="spacer"></div><divclass="spacer"></div><divclass="spacer"></div><divclass="spacer"></div><divclass="spacer"></div><divclass="spacer"></div></body>
JS
functionscrollFunction(){
var sticky1 = $('#firstHeader');
var sticky2 = $('#secondHeader');
sticky1.css({
position: "static",
top: 0
});
sticky2.css({
position: "static",
top: 0
});
$('body').css({
"padding-top": 0
});
var topOffset1 = sticky1.offset().top;
var topOffset2 = sticky2.offset().top;
var stickyHeight1 = sticky1.outerHeight();
var stickyHeight2 = sticky2.outerHeight();
var scrollHeight = $(window).scrollTop();
if(topOffset1 <= scrollHeight && scrollHeight < topOffset2 - stickyHeight1){
sticky1.css({
position: "fixed",
top: 0
});
sticky2.css({
position: "static",
top: 0
});
$('body').css({
"padding-top": stickyHeight1
});
}
elseif(scrollHeight >= topOffset2 - stickyHeight1 && scrollHeight < topOffset2){
sticky1.css({
position: "fixed",
top: - (scrollHeight - (topOffset2 - stickyHeight1))
});
sticky2.css({
position: "fixed",
top: stickyHeight1 - (scrollHeight - (topOffset2 - stickyHeight1))
});
$('body').css({
"padding-top": stickyHeight1 + stickyHeight2
});
}
elseif(scrollHeight >= topOffset2){
sticky1.css({
position: "static"
});
sticky2.css({
position: "fixed",
top: 0
});
$('body').css({
"padding-top": stickyHeight2
});
}
else{
sticky1.css({
position: "static",
top: 0
});
sticky2.css({
position: "static",
top: 0
});
$('body').css({
"padding-top": 0
});
}
}
$(window).scroll(scrollFunction);
Updated JS
This should solve the problem with having a flickery screen.
var topOffset1, topOffset2;
functionscrollFunction(){
var sticky1 = $('#firstHeader');
var sticky2 = $('#secondHeader');
var stickyHeight1 = sticky1.outerHeight();
var stickyHeight2 = sticky2.outerHeight();
var scrollHeight = $(window).scrollTop();
if(topOffset1 <= scrollHeight && scrollHeight < topOffset2 - stickyHeight1){
sticky1.css({
position: "fixed",
top: 0
});
sticky2.css({
position: "static",
top: 0
});
$('body').css({
"padding-top": stickyHeight1
});
}
elseif(scrollHeight >= topOffset2 - stickyHeight1 && scrollHeight < topOffset2){
sticky1.css({
position: "fixed",
top: - (scrollHeight - (topOffset2 - stickyHeight1))
});
sticky2.css({
position: "fixed",
top: stickyHeight1 - (scrollHeight - (topOffset2 - stickyHeight1))
});
$('body').css({
"padding-top": stickyHeight1 + stickyHeight2
});
}
elseif(scrollHeight >= topOffset2){
sticky1.css({
position: "static"
});
sticky2.css({
position: "fixed",
top: 0
});
$('body').css({
"padding-top": stickyHeight2
});
}
else{
sticky1.css({
position: "static",
top: 0
});
sticky2.css({
position: "static",
top: 0
});
$('body').css({
"padding-top": 0
});
}
}
$(function(){
topOffset1 = $('#firstHeader').offset().top;
topOffset2 = $('#secondHeader').offset().top;
});
$(window).scroll(scrollFunction);
JS For variable number of headers
Simply add the class .header
to your headers and this will work for any number of headers (1, 5, 100... You get the point).
This is a complete replacement for the above JS and each new header will push the old header off of the screen before it binds to the top.
See this updated jsfiddle
for an example of it in action: http://jsfiddle.net/5bkst/
var topOffset = newArray();
functionscrollFunction(){
var scrollHeight = $(window).scrollTop();
var headerCounter = 0;
var scrolled = 0;
var headerItems = $('.header').length;
$('.header').each(function(index, el){
var elementHeight = $(this).outerHeight();
var nextElementHeight = 0;
var nextElement;
if(index !== $('.header').length - 1){
nextElementHeight = $('.header').eq(index + 1).outerHeight();
nextElement = $('.header').eq(index + 1);
}
if(scrollHeight >= topOffset[headerCounter]
&& (scrollHeight < topOffset[headerCounter + 1] || headerCounter == headerItems-1)){
scrolled = 1;
if(scrollHeight >= topOffset[headerCounter + 1] - elementHeight){
$(this).css({
position: "fixed",
top: - (scrollHeight - (topOffset[headerCounter + 1] - elementHeight))
});
nextElement.css({
position: "fixed",
top: topOffset[headerCounter + 1] - scrollHeight
});
$('body').css({
"padding-top": elementHeight + nextElementHeight
});
returnfalse;
}
else{
$(this).css({
position: "fixed",
top: 0
});
nextElement.css({
position: "static",
});
$('body').css({
"padding-top": elementHeight
});
}
}
else{
$(this).css({
position: "static"
});
}
headerCounter++;
});
if(scrolled == 0){
$('body').css({
"padding-top": 0
});
}
}
$(function(){
$('.header').each(function(){
topOffset.push($(this).offset().top);
});
});
$(window).scroll(scrollFunction);
Solution 2:
If you want to switch headers than try this. FIDDLE
<headerclass="default"><divclass="default-cnt">
Default Content
</div><divclass="fixed-cnt">
Fixed Content
</div></header>
header {
width: 100%;
height: 120px;
padding: 10px;
letter-spacing: 1px;
}
.default {
background: #555;
position: relative;
color: #fff;
}
.fixed {
background: #01a8e7;
position: fixed;
top: 0;
left: 0;
color: #000;
}
.default.fixed-cnt {
display: none;
}
.fixed.default-cnt {
display: none;
}
$(function() {
var header = $('header');
var headOff = header.offset();
$(window).scroll(function() {
if($(this).scrollTop() > 120 + headOff.top && header.hasClass('default')) {
header.fadeOut('fast', function() {
$(this).removeClass('default').addClass('fixed').fadeIn('fast');
});
}
elseif($(this).scrollTop() <= 120 + header.height() && header.hasClass('fixed')) {
header.fadeOut('fast', function() {
$(this).removeClass('fixed').addClass('default').fadeIn('fast');
});
}
});
});
Post a Comment for "Replacing A Sticky Header With A Second Header When It Reaches The Currently Stuck Header"