Here you go are pretty similar:
http://jsfiddle.net/AlienWebguy/mvtP7/1/
HTML:
<div id="header1" class="header fixed"> <h2>Header1</h2> </div> <div id="header1_content"> <p>Lorem ipsum dolor sit amet...</p> </div> <div id="header2" class="header relative"> <h2>Header2</h2> </div> <div id="header2_content"> <p>Lorem ipsum dolor sit amet...</p> </div> <div id="header3" class="header relative"> <h2>Header3</h2> </div> <div id="header3_content"> <p>Lorem ipsum dolor sit amet...</p> </div>
CSS
p { background-color:#F0F0F0; } .header { background-color:#CCC; width:100%; top:0; left:0; } .header h2 { margin:20px; } .fixed { position:fixed; } .relative { position:static; } #header1_content { margin-top:80px; }
JQuery
$(function(){ var lastScrollTop = 0; $(window).scroll(function(event){ var currentScrollTop = $(this).scrollTop(); if (currentScrollTop > lastScrollTop){ // Scrolling down $('.header').each(function(){ if($(this).hasClass('fixed')) { var _next_header = $(this).nextUntil('.header').next('.header'); if($(_next_header).length > 0) { if(($(this).offset().top + $(this).height()) >= $(_next_header).offset().top) { // Bottom of header hit top of next header $(this).removeClass('fixed').addClass('relative'); $(_next_header).removeClass('relative').addClass('fixed'); } } } }); } else { // Scrolling up $('.header').each(function(){ if($(this).hasClass('fixed')) { var _prev_header = $(this).prevUntil('.header').prev('.header'); if($(_prev_header ).length > 0) { if($(this).offset().top <= ($('#' + $(_prev_header).attr('id') + '_content').offset().top + $(this).height())) { // Top of header hit bottom of previous content box $(this).removeClass('fixed').addClass('relative'); $(_prev_header).removeClass('relative').addClass('fixed'); } } } }); } lastScrollTop = currentScrollTop; }); });
Thus, in essence, we create basic conflict detection. When we scroll down, we find that the bottom of the current heading collides with the top of the next heading. If this happens, we will replace it. When we scroll up, we find that the top of the current header collides with the bottom of the previous content container and makes a swap.
If you go to the next level to more accurately emulate the iPhone menu, you probably want to re-place the headers inside the DOM on the fly when they collide, which will give the illusion that one of them pushes the other way, "as soon as the previous disconnected from the screen, you applied fixed positioning to the new heading. This demo should fix you on the right track :)
Hope this helps!
Alienwebguy
source share