fullpage.js and adding/removing class at top of page - javascript

I'm having trouble with fullpage.js (https://github.com/alvarotrigo/fullPage.js/) at http://vatuvara.com/
Basically I want #masthead to have a class of 'black-nav' added if the visitor is not in the first section of the page, and then I want this class removed if they are in the first section of the page.
$(document).ready(function() {
$('#primary').fullpage({
menu: '#masthead',
afterLoad: function(anchor, index){
if(index == 1){
$('#masthead').removeClass('black-nav');
}else{
$('#masthead').addClass('black-nav');
}
}
});
});
This seems to work fine, except when I add a link to a section on the homepage eg. the 'About' nav links to http://vatuvara.com/#TheIslands. So I added a secondary script to change the masthead's class when #primary-menu a is clicked.
$(document).ready(function() {
$("#primary-menu a").click(function() {
$('#masthead').addClass('black-nav');
});
});
But the results are a bit mixed. Clicking on 'About', then scrolling back to the top of the page works about 50% of the time — the 'black-nav' class is removed, but the rest of the time it doesn't so #masthead continues to have the .black-nav class.
I also have another script which has similar results. I want the nav to be hidden when scrolling down, but re-appear when scrolling up. So I have this script below which seems to work about 70% of the time, the rest of the time #masthead continues to have the .black-nav class. And if you scroll to the very bottom of the page, then scroll back up the success rate drops to about 50%
// Hide Header on on scroll down
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('#masthead').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
$('#masthead').fadeOut();
} else {
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$('#masthead').fadeIn();
}
}
lastScrollTop = st;
}

I solved this by removing fullpage's afterLoad function and instead using a .scrollTop function:
$(document).ready(function() {
$('#primary').fullpage({
anchors: ['home', 'TheIslands', 'TheResort', 'Accomodation', 'AccomodationPhoto', 'Nature', 'NaturePhoto', 'CulinaryExperience', 'CulinaryExperienceLocations', 'CulinaryExperiencePhoto', 'CulinaryExperienceSeafood', 'Spa', 'SpaAbout', 'Activities', 'ActivitiesPhoto', 'Culture', 'Travel', 'Footer'],
menu: '#masthead',
slidesNavigation: true,
slidesNavPosition: 'bottom',
controlArrows: false,
scrollBar: true,
responsiveWidth: 900,
});
});
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
$("#masthead").addClass("black-nav");
} else {
$("#masthead").removeClass("black-nav");
}
});

Related

How to detect when a user is no longer scrolling to initiate the addition/removal of a class

I'm working on a prototype that has a navigation bar that hides when a user scrolls down on the page and shows when the user scrolls up. I would like to take this a step further by setting an event that tracks when the user is no longer scrolling and animates the navigation panel back onto the page after a short timeframe (1.5 - 2 seconds).
I have read up on how I would go about doing this but I haven't been able to find anything that meets my needs completely.
Here is my prototype for reference: https://codepen.io/v_for_vinsanity/pen/2af1bfb20ae1578466943c7356de7348
Here is the jquery I'm using to show/hide the navigation bar:
var scrollSet = null;
var didScroll = false;
var windowTop = $(window).scrollTop();
function scrollUpdate () {
didScroll = true;
windowTop = $(window).scrollTop();
}
function scrollTicker () {
if(didScroll) {
if(windowTop > scrollSet) {
$('body').addClass('hide-nav')
scrollSet = windowTop;
}
else if(scrollSet > windowTop){
$('body').removeClass('hide-nav')
scrollSet = windowTop;
}
didScroll = false
}
requestAnimationFrame(scrollTicker);
}
$(window).scroll(scrollUpdate);
scrollTicker();

Too many scroll events for smooth scrolling

Hello there I've been trying to find a fix for the many scroll events firing on one scroll. This is the only thing close to working for me so far. I want to smoothscroll between two divs (#boxes and #header) I want to use the scroll bar to trigger this smooth scroll and not a button. Any suggestions on how to only take one scroll event? I also used solutions based from prev stackoverflow questions. I used my own locator instead of offsets because thats also unreliable
$(window).scroll(function () {
if (timer) {
window.clearTimeout(timer);
}
timer = window.setTimeout(function () {
if (locator == 0) {
id = $("#boxes");
locator = 1;
} else if (locator = 1) {
id = $("#header");
locator = 0;
}
// target element
var $id = $(id);
if ($id.length === 0) {
return;
}
// top position relative to the document
var pos = $id.offset().top;
// animated top scrolling
$('html, body').animate({scrollTop: pos}, 1500, function () {
$('html, body').clearQueue();
$('html, body').stop();
});
}, 2);
});
So, to be clear, you want any minor scroll event to scroll between one item and the other? Note that when a user scrolls, there is a "momentum" that the browser implements, and you'll be battling with that.
Regardless: You don't need to wrap this in a setTimeout. Right now, your javascript is creating a new setTimeout function that is being fired every 2ms. Scroll events occur with every pixel of movement in the scroll, so if you scroll 100px, you're going to be firing 100 times every 2ms. (That's 50,000 times).
Instead, have a a variable (isScrolling) track the state, so, if you're in the middle of scrolling, the function won't fire.
var isScrolling = false;
var locator = 0;
$(window).scroll(function () {
if (isScrolling) return false;
if (locator == 0) {
id = $("#boxes");
locator = 1;
} else if (locator = 1) {
id = $("#header");
locator = 0;
}
// target element
var $id = $(id);
if ($id.length === 0) {
return;
}
// top position relative to the document
var pos = $id.offset().top;
// animated top scrolling
isScrolling = true;
$('html, body').animate({scrollTop: pos}, 1500, function () {
$('html, body').clearQueue();
$('html, body').stop();
isScrolling = false;
});
});
Here's a JSbin: http://jsbin.com/jugefup/edit?html,css,js,output

Scroll control with JQuery / Java Script

I am looking for to mimic the same scroll behavior the new Flickr website has at https://www.flickr.com/#section-1.
No matter how hard or fast you move your mouse scroll wheel the result is the same.
I know this is a kind of parallax website but I am more interested in the scroll control.
This is what I am doing right now using this plugin https://github.com/ultrapasty/jquery-disablescroll:
var mypos = $(window).scrollTop();
var up = false;
var newscroll;
$(window).scroll(function () {
newscroll = $(window).scrollTop();
if (newscroll > mypos && !up) {
$(window).disablescroll(); //disable scroll
//$('body').addClass('stop-scrolling'); //a css that inputs an overflow hidden
$('#video_bkg').stop().animate({
height: 'toggle',
opacity: 'toggle'
}, 500);
up = !up;
} else if(newscroll < mypos && up) {
$('#video_bkg').stop().animate({
height: 'toggle',
opacity: 'toggle'
}, 500, function() {
$(window).disablescroll('undo'); //reenable scroll
});
up = !up;
}
mypos = newscroll;
});
But none of this equals the Flickr's effect.
Here's an example that does this using the fullPage jQuery plugin.
Use
$(document).ready(function() {
$('#fullpage').fullpage();
});
to initialize the script.

Scroll down to special div

I'm trying to make a simple jQuery plugin that will scroll page down until it reaches special div like a #stopscroll. I got a simple jQuery plugin to stop scroll on special size:
$(window).scroll(checkscroll);
function checkscroll(){
var top = $(window).scrollTop();
if(top > 300){
$('#share_box').fadeOut('slow');
}else{
$('#share_box').fadeIn('slow');
}
}
checkscroll();
How do I make it scroll to a special div instead of scrolling a specified size? I want it to stop scrolling when div #sharebox reach #stopscroll.
I don't know if I understand your question correct but I think I had the same problem a while back. I fixed it like this:
$(document).ready(function() {
/** HIDE MENU **/
$(".menu").css("margin-top", "-88px");
var mustSlideDown = true;
var mustSlideUp = false;
$(window).scroll(function() {
var verschil = ($(window).scrollTop() / 5);
if (verschil > 40 && mustSlideDown) {
$('.menu').animate({'margin-top': '0px' }, {duration: 500, queue: false});
mustSlideDown = false;
mustSlideUp = true;
}
else if (verschil < 40 && mustSlideUp) {
$('.menu').animate({'margin-top': '-88px' }, {duration: 500, queue: false});
mustSlideUp = false;
mustSlideDown = true;
}
});
});
Didn't get much of your English, but maybe you are looking for this-
Window.location='#scollDiv';

Track the scroll position beyond elements

I'm putting together a jQuery plugin. The plugin takes panels, and auto-sizes their height. So I start off with something like this:
<div class="panel">Test 1</div>
<div class="panel">Test 2</div>
<div class="panel">Test 3</div>
The code for that looks something like:
sizePanels: function(){
panels.each(function(){
$(this).height(docHeight);
});
},
There is a down button, that when clicked, will take the user to the next $(".panel):
nextPanel: function(){
$.scrollTo($(".panel:eq(" + panelIndex + ")"), 250, { easing: "swing" });
}
With that, I'm keeping track of the panel index that their on:
if (panelIndex < (panelCount - 1) ) {
panelIndex += 1;
}
I'm trying to figure out a way to track if they happen to scroll manually, and pass one of the elements, to then increase the "panelIndex", so that the button doesn't move them up instead of down because it was never incremented properly due to the user using the scroll bar instead of the button. This is what I have so far:
$(window).scroll(function(){
panels.each(function(index){
if ($(window).scrollTop() > $(this).scrollTop()) {
panelIndex = index;
// console.log(index);
}
});
if (panelIndex < panelCount - 1){
s.showDownButton();
}
});
The code excessively checks and feels somewhat overboard. is there a better way to do it?
An easy optimization is to only calculate the scrollTop once and to exit the each loop when a match is found. You can exit a $.each loop by returning false.
$(window).scroll(function(){
var scrollTop = $(window).scrollTop();
panels.each(function(index){
if (scrollTop > $(this).scrollTop()) {
panelIndex = index;
} else {
return false;
}
});
if (panelIndex < panelCount - 1){
s.showDownButton();
}
});
The next way that I would suggest optimizing this is to pre-calculate the scrollTop of each panel on page load (and when the viewport is resized). If you store these values in an array, then you can loop through them very quickly.
Here is some rough code to illustrate the idea:
var panelTops = [];
findPanelTops(); // calculate on load
$(window).on("resize", findPanelTops); // calculate on resize
function findPanelTops() {
panelTops = [];
panels.each(function(index) {
panelTops.push($(this).scrollTop());
});
}
$(window).scroll(function(){
var scrollTop = $(window).scrollTop();
for (var i = 0; i < panelTops.length; i++) {
if (scrollTop > panelTops[i]) {
panelIndex = i;
} else {
break;
}
};
if (panelIndex < panelCount - 1){
s.showDownButton();
}
});
The scroll event can fire a lot and very quickly, so you want to keep the amount of computation as minimal as possible. One way to get around all of this is to implement a scrollend handler. This will only fire when the scroll event has appeared to have stopped.
Here is some basic code for doing that. It will fire when the scroll event has stopped for more than 500ms:
var scrollTimeout = null;
function onScroll() {
if (scrollTimeout) {
clearTimeout(scrollTimeout);
}
scrollTimeout = setTimeout(onScrollEnd, 500);
}
function onScrollEnd() {
// Scrolling has stopped
// Do stuff ...
scrollTimeout = null;
}
$(window).on("scroll", onScroll);

Categories

Resources