Class not always applied when user is at top of the page - javascript

I am using the following code to apply different classes to #nav depending if the user scrolls UP, DOWN, or is at the top of the page.
.nav-down applied when user scrolls up
.nav-up applied when user scrolls down
.nav-down-top when user scrolls to the top of the page
code
jQuery(document).ready(function($){
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('nav').outerHeight(true);
$(window).scroll(function(event) { didScroll = true; });
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 100);
function hasScrolled() {
if($( window ).width() > 768) {
var st = $(this).scrollTop();
if (Math.abs(lastScrollTop - st) <= delta)
return;
if (st > lastScrollTop) {
// Scroll Down
$('#s-nav').removeClass('nav-down').removeClass('nav-down-top').addClass('nav-up');
} else {
// Scroll Up (# top of screen)
if (st === 0) {
$('#s-nav').removeClass('nav-up').removeClass('nav-down').addClass('nav-down-top');
} else { //if (st + $(window).height() < $(document).height()) {
$('#s-nav').removeClass('nav-up').removeClass('nav-down-top').addClass('nav-down');
}
}
}
lastScrollTop = st;
}
});
The problem is that when the user is at the top of the page or scrolls to the top .nav-down-top doesn't always get applied. This often happens when the user doesn't scroll very far to get to the top. I'm not sure how to ensure that .nav-down-top is applied when the user is at the top of the page.

$(function(){
var shrinkHeader = 300;
$(window).scroll(function() {
var scroll = getCurrentScroll();
if ( scroll >= shrinkHeader ) {
$('.navbar-fixed').addClass('class');
}
else {
$('.navbar-fixed').removeClass('oneclass');
$('.navbar-fixed').addClass('otherclass');
}
});
function getCurrentScroll() {
return window.pageYOffset || document.documentElement.scrollTop;
}
});
Try this script cleaner and tell me if it worked

What you seem to want is this:
var el = $('#test1')
$(window).scroll(function(){
if($(window).scrollTop() > 50){
console.log("addClass")
$(el).addClass('slideUp');
} else {
console.log("removeClass")
$(el).removeClass('slideUp');
}
})
https://jsfiddle.net/m0nz41ep/1/
You do not need to set an interval for the window to check the information, since the scroll is already an event that checks the window whenever you input information. :)
Also, are you doing animations?
You need to tell the CSS file that the divs you want to manipulate will be animated.
-webkit-transition: all 1s; // Chrome
-moz-transition: all 1s; // Mozilla
-o-transition: all 1s; // Opera
transition: all 1s;
If it's just one div add it to the id for the div, if it's multiple, add it to a class and add the class to all of the divs. The rest of the code should do the magic!

Related

Jquery mobile sticky header

I have a jquery mobile header div (data-role="header" data-position="fixed") with two toolbars inside in a layout like this:
_____________________
|XXXXXXXXXXXXXXXXXXX|
|YYYYYYYYYYYYYYYYYYY|
and I want to reproduce the effect of WhatsApp, where scroll down hides toolbar XXXXXXXX and scroll up shows toolbar XXXXXXXXXX. Toolbar YYYYYY always visible.
By using window.onscroll this can be achieved by adding/removing a class with top:-50px; upon scroll down/scroll up.
It works, however, it works only when the page is loaded for the first time or it is reached with a link having rel=external. In all other cases, it is impossible to see the effect of the added class. I have also tried .addClass("sticky").enhanceWithin() with no effect.
Any suggestion to make this to work every time?
Here the code:
var didScroll = false;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = 20;
$(document).on("scroll", function(event){
didScroll = true;
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
function hasScrolled() {
var currentScroll = $(this).scrollTop();
if(currentScroll >= 200) {
$("#scrollToTop").show();
} else {
$("#scrollToTop").hide();
}
if(Math.abs(lastScrollTop - currentScroll) <= delta)
return;
if (currentScroll > lastScrollTop && currentScroll > navbarHeight){
$('#PageHeader').removeClass('nav-down').addClass('sticky');
} else {
if(currentScroll + $(window).height() < $(document).height()) {
$('#PageHeader').removeClass('sticky').addClass('nav-down');
}
}
lastScrollTop = currentScroll;
}
I hope my fiddle will help you out:
[http://jsfiddle.net/Lfve19u0/]
Ramon.

How to show and hide menu based on start and scroll

I have two menus on a page, I am trying to show the one when the page is loaded and the other when there is a scroll.
This is my page Link
I would like to show the white part when position is at the top
and the blue part when there is a scroll past the top position
This is what am trying presently
<script type="text/javascript" src="//code.jquery.com/jquery-git.js"></script>
<script type='text/javascript'>//<![CDATA[
$(function(){
// Hide Header on on scroll down
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('header').outerHeight();
$(window).scroll(function(event){
didScroll = true;
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
function hasScrolled() {
var st = $(this).scrollTop();
// Make sure they scroll more than delta
if(Math.abs(lastScrollTop - st) <= delta)
return;
// If they scrolled down and are past the navbar, add class .nav-up.
// This is necessary so you never see what is "behind" the navbar.
if (st > lastScrollTop && st > navbarHeight){
// Scroll Down
$('header').removeClass('nav-bar-below op-page-header cf').addClass('banner include-nav');
} else {
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$('header').removeClass('banner include-nav').addClass('nav-bar-below op-page-header cf');
}
}
lastScrollTop = st;
}
});//]]>
</script>
can some one please help its not working for me
You can just detect if the scroll is at the top of the page or not whenever scroll event fired. if yes, show white header, and vice versa
$(window).scroll( function() {
var scrollPosition = $(window).scrollTop();
if(scrollPosition === 0) {
//show white header
}
else {
//show blue header
}
}
Of course you have to make sure when page first load, it show the white one first (use css). since the code above won't run Until user do scroll (fire this event)
*EDIT
for this :
"and the blue part when there is a scroll past the top position"
you can try this plugin
http://stickyjs.com/
sample code for fix the menu at top position.
$(document).scroll(function() {
var y = $(document).scrollTop()
var header = $('.include-nav');
var blue-menu = $('.cf');
var screenHeight = header.height();
if (y >= screenHeight) {
blue-menu.css({
position : "fixed",
"top" : "0",
"left" : "0"
});
header.css("position", "relative");
} else {
blue-menu.css("position", "relative");
}
});

Hide menu on scroll down and show on scroll up

I made this snippet code to hide menu on scroll down and show on scroll up but I have some issues, when I scroll to top the menu still have fixed position, how I can resolve this problem, Thanks!
JAVSCRIPT :
$(window).bind('scroll', function () {
if ($(window).scrollTop() > 500) {
$('.mainmenu').addClass('nav-down');
}
});
// Hide Header on on scroll down
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('.mainmenu').outerHeight();
$(window).scroll(function(event){
didScroll = true;
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 500);
function hasScrolled() {
var st = $(this).scrollTop();
// Make sure they scroll more than delta
if(Math.abs(lastScrollTop - st) <= delta)
return;
// If they scrolled down and are past the navbar, add class .nav-up.
// This is necessary so you never see what is "behind" the navbar.
if (st > lastScrollTop && st > navbarHeight){
// Scroll Down
$('.mainmenu').removeClass('nav-down').addClass('nav-up');
} else {
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$('.mainmenu').removeClass('nav-up');
}
}
lastScrollTop = st;
}
CSS :
.mainmenu {
background: #222;
height: 50px;
padding: 0 15px;
width: 80%;
margin: 0 auto;
}
.nav-down{
position: fixed;
top: 0;
transition: top 0.2s ease-in-out;
width: 100%;
}
.nav-up {
top: -50px;
}
Demo : jsfiddle
To you first listener, just add an else statement as follows:
$(window).bind('scroll', function () {
if ($(window).scrollTop() > 150)
$('.mainmenu').addClass('nav-down');
else
$('.mainmenu').removeClass('nav-down');
});
Also note that you don't need a setInterval() for the second listener, see jsfiddle
I tested it and it works fine!!
$(window).bind('scroll', function () {
if ($(window).scrollTop() > 500) {
$('.mainmenu').addClass('nav-down');
}
else
{
$('.mainmenu').removeClass('nav-down');
}
});
Add an else to your scrollTop with a removeClass and you should be fine, I tested it and it works. Here
$(window).bind('scroll', function () {
if ($(window).scrollTop() > 500) {
$('.mainmenu').addClass('nav-down');
}
else
{
$('.mainmenu').removeClass('nav-down');
}
});
Detect nav direction with a variable
var lastscrolltop=0;
jQuery(window).bind('scroll', function () {
if (jQuery(window).scrollTop() > lastscrolltop)
jQuery('.mainmenu').addClass('nav-up');
else
jQuery('.mainmenu').removeClass('nav-up');
lastscrolltop=jQuery(window).scrollTop();
});
and use css transition for a smooth show/hide
.mainmenu {
transition:all 0.5s ;
}
Your way is too much complicated.
You can hide the menu on scroll with a simple transition using jQuery .fadeIn() and fadeOut(), without the need for css.
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
$('.mainmenu').fadeOut('fast');
} else {
$('.mainmenu').fadeIn('fast');
}
lastScrollTop = st;
});

jquery scroll() and on(mousemove) messing up

I'm using this function to hide my header when scrolling down, and showing it again when scrolling up
$(function(){
var lastScrollTop = 0, delta = 5;
$('.item').scroll(function() {
var nowScrollTop = $(this).scrollTop();
if(Math.abs(lastScrollTop - nowScrollTop) >= delta){
if (nowScrollTop > lastScrollTop){
$('header').fadeTo(0,0); // scrolling down
} else {
$('header').fadeTo(0,1); // scrolling up
}
lastScrollTop = nowScrollTop;
}
});
});
Additionally I'm using this function to show the header when the cursor is in the top 200px of the page:
$(window).on('mousemove', function(e) {
if ( e.pageY < 200 ) {
$('header').fadeTo(0,1);
}
});
The problem is that when I'm scrolling with my mouse being in the top 200px of the window, the two functions collide, and the header keeps toggling between being shown and hidden.
Now, I've read elsewhere that I need to unbind and bind the mousemove when scrolling. I don't know however how to do that.
EDIT:
Here's a link to jsfiddle: https://jsfiddle.net/zrmg646L/
EDIT 2:
Here's a link to the jsfiddle with the solution in action: http://jsfiddle.net/zrmg646L/3/
Try this. Unbind mousemove on scroll and rebind it after not scrolled for 250ms
function fadeHeader(e) {
if ( e.pageY < 200 ) {
$('header').fadeTo(0,1);
}
}
$(function(){
$(window).mousemove(fadeHeader);
var lastScrollTop = 0, delta = 5;
$('.item').scroll(function() {
$(window).unbind('mousemove', fadeHeader);
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function() {
$(window).mousemove(fadeHeader);
}, 250));
var nowScrollTop = $(this).scrollTop();
if(Math.abs(lastScrollTop - nowScrollTop) >= delta){
if (nowScrollTop > lastScrollTop){
$('header').fadeTo(0,0);
} else {
$('header').fadeTo(0,1); // scrolling up
}
lastScrollTop = nowScrollTop;
}
});
});

Change background color if position fixed

I have this simple navigation that was built to hide a fixed header when scrolling down. When you scroll up it will reappear for easy navigation. It works great! However, I need it changed up a bit and not sure how to accomplish this.
When the position is fixed at the absolute top of the page I need the header to be transparent. When the position is then scrolled down and then scrolled up a little. I need the background to be blue until it reaches the absolute top then again change to transparent.
http://codepen.io/anon/pen/VYPGyg
here is the jQuery in question:
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('header').outerHeight();
$(window).scroll(function(event){
didScroll = true;
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
function hasScrolled() {
var st = $(this).scrollTop();
// Make sure they scroll more than delta
if(Math.abs(lastScrollTop - st) <= delta)
return;
// If they scrolled down and are past the navbar, add class .nav-up.
// This is necessary so you never see what is "behind" the navbar.
if (st > lastScrollTop && st > navbarHeight){
// Scroll Down
$('header').removeClass('nav-down').addClass('nav-up');
} else {
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$('header').removeClass('nav-up').addClass('nav-down');
}
}
lastScrollTop = st;
}
Any help would be great!
I would use your nav-down and nav-up classes, since they're getting added anyways. When you use CSS to handle styling, you're (usually) better separating concerns amongst various aspects of your software. CSS should usually handle presentation, except where it's functionality is limited or not programmatic enough (enter javascript).
For example, take your .nav-down class and adjust the transparency:
Updated codepen:
http://codepen.io/anon/pen/YPNOLM
Added some logic to your function:
function hasScrolled() {
var st = $(this).scrollTop();
// Make sure they scroll more than delta
if(Math.abs(lastScrollTop - st) <= delta)
return;
// If they scrolled down and are past the navbar, add class .nav-up.
// This is necessary so you never see what is "behind" the navbar.
if (st > lastScrollTop && st > navbarHeight){
// Scroll Down
$('header').removeClass('nav-down').addClass('nav-up');
} else {
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$('header').removeClass('nav-up').addClass('nav-down');
}
// the 100 can be whatever height you think it should be at
if($(window).scrollTop() > 100) {
$('header').addClass('notTop')
} else {
$('header').removeClass('notTop')
}
}
lastScrollTop = st;
}
And an opacity property:
header.nav-down {
position: fixed;
width: 100%;
top: 0;
transition: top 0.2s ease-in-out;
z-index: 1;
background: #fff;
padding: 25px 0px 0px 0px;
opacity: 0.8
}
And:
header.nav-down.notTop {
background-color: blue
}

Categories