Reputation: 5129
These if statements are always making me dizzy. If have a page with a header, and a hidden header above that in the markup.
<div id="headerfloat" style="display:none;">
<p>Floated header</p>
</div>
<div id="header">
<p>Header</p>
</div>
The idea is that whenever the page is scrolled down more than 225px, the #headerfloat
should appear, and dissapear when topScroll is less than 225px. And I managed to get this working with javascript and jQuery, but when I test it on iPhone, it's very sluggish. And I'm pretty sure it's because the code is run at each scroll event. And even if #headerfloat
is visible, the code still executes. Even though it doesn't have to at that point.
So, I need to make sure the code only run once, when it's needed. My first thought was to add and remove classes like .open
and .closed
to #headerfloat
. And run if statements on those during the scroll event. But is that the most efficient way of doing it?
My so far, ugly snippet:
jQuery(window).scroll(function () {
var headerfloat = $("#header_float");
var top = jQuery(window).scrollTop();
if (top > 225) // height of float header
{
if (!$(headerfloat).hasClass("closed")) {
$(headerfloat).addClass("boxshadow", "", 100, "easeInOutQuad").slideDown().addClass("open").removeClass("closed");
}
} else {
$(headerfloat).removeClass("boxshadow", "", 100, "easeInOutQuad").removeClass("closed").slideUp();
}
});
Edit: So after laconbass's awesome response, this is the code I ended up with:
var mainHeader = $('#header')
, top_limit = mainHeader.outerHeight()
, $window = $(window)
;
var header_float = $('#header_float')
bindEvent();
function bindEvent() {
$window.scroll( scrollEvent );
}
function scrollEvent() {
var top = $window.scrollTop();
// avoid any logic if nothing must be done
if ( top < top_limit && !header_float.is(':visible')
|| top > top_limit && header_float.is(':visible')
) return;
// unbind the scroll event to avoid its execution
// until slide animation is complete
$window.unbind( 'scroll' );
// show/hide the header
if ( top > top_limit ) {
header_float.slideDown( 400, bindEvent );
} else {
header_float.slideUp( 400, bindEvent );
}
};
Upvotes: 0
Views: 2690
Reputation: 17815
I've assumed the following:
fixed
positioned header when the page scrolls down (aka fixed header
).fixed headed
is a clone of the page main header, with the class fixed
.fixed header
is shown when the page scrolls down more than the header height.fixed header
is hidden when the page scrolls up enough to show the main page header.Performance tips:
var mainHeader = $('header')
, header = mainHeader.clone().addClass('fixed').appendTo('body')
, top_limit = header.outerHeight()
;
bindEvents();
function bindEvents() {
$(window).scroll( scrollEvent );
}
function scrollEvent() {
var top = $(window).scrollTop();
// avoid any logic if nothing must be done
if ( top < top_limit && !header.is(':visible')
|| top > top_limit && header.is(':visible')
) return;
// unbind the scroll event to avoid its execution
// until slide animation is complete
$(window).unbind( 'scroll' );
// show/hide the header
if ( top > top_limit ) {
header.slideDown( 400, bindEvents );
} else {
header.slideUp( 400, bindEvents );
}
};
<header>
<h1>Awesome header</h1>
</header>
<div>
<!-- the page content -->
</div>
/* the real code needed */
header.fixed {
display: none;
position: fixed;
top: 0;
}
Upvotes: 2
Reputation: 362
two way:
1,on scroll,and if you have done your want, remove the scroll event.
2,var a variable,default is false, on scroll, if the variable is false,to do you want,and set the variable to true; if the variable is true already, do nothing(or others you want)
Upvotes: 0