Fixed header navigation and scrollTo() next/previous elements - javascript

First off I use this code to make the navigation bar always stay fixed;
After adding CSS position absolute:
var yOffset = $("#header").offset().top;
$(window).scroll(function() {
if ($(window).scrollTop() > yOffset) {
$("#header").css({
'top': 0,
'position': 'fixed'
});
} else {
$("#header").css({
'top': yOffset + 'px',
'position': 'absolute'
});
}
});
But now my next/previous key events which used to scroll to next element is not catching the right element position.
here is my code for browsing next/prev element.
// scroll to next post
function scrollToNew () {
scrollTop = $(window).scrollTop();
$('.post').each(function(i, h1){
h1top = $(h1).offset().top;
if (scrollTop < h1top) {
$.scrollTo(h1);
return false;
}
});
}
// scroll to previous post
function scrollToLast () {
scrollTop = $(window).scrollTop();
var scrollToThis = null;
$('.post').each(function(i, h1) {
h1top = $(h1).offset().top;
if (scrollTop > h1top) {
scrollToThis = h1;
} else {
return false;
}
});
if(scrollToThis != null) {
$.scrollTo(scrollToThis);
}
}
I simply used to fire the scrollToNew when key pressed and it was working until I made the fixed navigation (#header) because it stays always on top so the heading of post which user scrolls to, becomes invisible. I do not know how to get around this issue.
Any suggestions are greatly helpful really.

Here is the fix.
I added the height of navigation header into offset. Which is exact 61pixels. Problems solved.
// scroll to next post
function scrollToNew () {
scrollTop = $(window).scrollTop();
$('.post').each(function(i, h1){
h1top = $(h1).offset().top;
if (scrollTop < h1top - 61) {
$.scrollTo(h1, {offset: {left: 0, top: -61}});
return false;
}
});
}
// scroll to previous post
function scrollToLast () {
scrollTop = $(window).scrollTop();
var scrollToThis = null;
$('.post').each(function(i, h1) {
h1top = $(h1).offset().top;
if (scrollTop > h1top - 61) {
scrollToThis = h1;
} else {
return false;
}
});
if(scrollToThis != null) {
$.scrollTo(scrollToThis, {offset: {left: 0, top: -61}});
}
}

Related

Smooth mouse scroll upward using Jquery and CSS

I am try to make a smooth scroll upward and downward but having issue with the follow up image. t
$(window).scroll(function(event) {
var scroll = $(window).scrollTop();
if (scroll < 400) {
$('#two').css('position', 'fixed');
$('#three').css('position', 'fixed');
}
if (scroll > 400 && scroll < 900) {
$('#two').css('position', 'absolute');
$('#three').css('position', 'fixed');
}
});
https://jsfiddle.net/KingJef/6q47vmhn/32/
I have found a question with a similar dynamics, following the proposal of the author of the question it is possible to do the same in your question:
$(document).ready(function() {
$(window).scrollTop(1);
var img1 = $('#one');
var posimg1 = img1.position().top;
var img2 = $('#two');
var posimg2 = img2.position().top;
var img3 = $('#three');
var posimg3 = img3.position().top;
$(window).scroll(function(event) {
var scroll = $(window).scrollTop();
if (scroll <= posimg1) {
img1.addClass('latched');
} else {
img1.removeClass('latched');
}
if (scroll <= posimg2) {
img2.addClass('latched');
} else {
img2.removeClass('latched');
}
if (scroll <= posimg3) {
img3.addClass('latched');
}
});
});
Demo: https://jsfiddle.net/pr0mming/ybar8onj/14/
Apparently the error is to preserve the absolute images with css, instead of this they are left in fixed and the property would be eliminated once the scroll is exceeded (visibility level) but otherwise the images should be kept in fixed.
But there is a shorter solution with the same algorithm, of course, it is simply to add this magic css and remove it as the case may be:
$(document).ready(function() {
$(window).scroll(function(event) {
var scroll = $(window).scrollTop();
if (scroll < 500) {
$('#two').css('position', 'fixed');
$('#three').css('position', 'fixed');
}
if (scroll > 500 && scroll < 1600) {
$('#two').removeAttr( 'style' );
$('#three').css({ position: 'fixed', top: 0, width: 'auto' });
}
else {
$('#two').css({ position: 'fixed', top: 0, width: 'auto' });
$('#three').css({ position: 'fixed', top: 0, width: 'auto' });
}
});
});

How can I control the mouse scroll event and after that do an animation on the html, body?

I'm facing a very strange error, which is animation on body during mouse scroll. I think its happening because of the jQuery event window.scroll. I have tried a lot of things like unbinding of animation on mouse scroll, but nothing works. Below is my code.
$(document).on("scroll", function () {
var lastScrollTop = 0;
var windowHeight = $(window).scrollTop();
var seccion1 = $("#seccion1").height();
var seccion2 = $("#seccion2").offset().top;
var alturaseccion2 = $("#seccion2").height();
//this function returns in which section is the user with the scroll
var localizacion = comprobarSeccion(seccion1, seccion2);
if (windowHeight > lastScrollTop) {
// down scroll
console.log("scrollabajo");
if (localizacion == 1) {
$("html, body").animate({
scrollTop: $("#seccion2").offset().top
}, 2);
$(document).bind("scroll");
} else if (localizacion == 2) {
if (windowHeight >= ((alturaseccion2 * 0.80) + seccion2) && windowHeight <= (alturaseccion2 + seccion2)) {
} else {
}
}
} else {
// up scroll
console.log("scrollarriba");
}
lastScrollTop = windowHeight;
});
ยดยดยด
I'm not sure what you are trying to accomplish, but if your trying to trigger an event with a specific scroll value you can use the code below
$(window).scroll(function () {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
alert("scroll is greater than 500 px)
} else if(scroll==500){
alert("scroll has hit 500px");
}
});

How to make two different functions work on window resize

I want to make a sticky banner, which becomes fixed at top when it is scrolled and unsticks at the end of the page. The document height is dependent upon images, that's why I use window load event. I have the following code:
function saleBanner() {
$(window).bind("load", function() {
// Make sale banner fixed-at-top
var s = $('.sale-container');
var pos = s.offset();
var maxTop = $(document).outerHeight() - 828 - s.outerHeight(); // 828 is the total height of site footer and sign up form
function fixedBanner() {
var currentTop = $(window).scrollTop();
if (currentTop >= pos.top && currentTop < maxTop) {
s.attr("style", ""); //kill absolute positioning
s.addClass('fixed-at-top'); //stick it
} else if (currentTop >= maxTop) {
s.removeClass('fixed-at-top'); //un-stick
s.css({bottom: 0}); //set sticker right above the footer
} else {
s.removeClass('fixed-at-top'); //top of page
}
}
$(window).scroll(fixedBanner);
});
}
saleBanner();
I want to make this function work on window resize as well. So I added the following code:
function resizeBanner() {
var viewportWidth = $(window).width();
if (viewportWidth > 767) {
saleBanner();
}
}
I have one more function resizeWindow for mobile menu, which I also need to work on window resize. So when I put this two functions together, they don't work (although they work on window resize separately):
$(window).resize(function(e) {
resizeWindow(e);
resizeBanner(e);
});
Where is my mistake? How can I make both functions work on window resize?
Update: Here is the whole code for resizeWindow function. It's rather long, but may be it would be helpful for the answer.
// Mobile menu
var MQM = 768;
var viewportWidth = $(window).width();
function navSlide() {
var headerHeight = $('.cd-header').height();
$(window).on('scroll', {previousTop: 0}, function () {
var currentTop = $(window).scrollTop();
//check if user is scrolling up
if (currentTop < this.previousTop ) {
//if scrolling up...
if (currentTop > 0 && $('.cd-header').hasClass('is-fixed')) {
$('.cd-header').addClass('is-visible');
} else {
$('.cd-header').removeClass('is-visible is-fixed');
}
} else {
//if scrolling down...
if(!$('.cd-header').hasClass('menu-is-open')) {
$('.cd-header').removeClass('is-visible');
}
if( currentTop > headerHeight && !$('.cd-header').hasClass('is-fixed')) $('.cd-header').addClass('is-fixed');
}
this.previousTop = currentTop;
});
}
// Primary navigation slide-in effect on load
if(viewportWidth < MQM) {
navSlide();
}
function addOverflow() {
$('html').addClass('overflow-hidden');
$('body').addClass('overflow-hidden');
}
function removeOverflow() {
$('html').removeClass('overflow-hidden');
$('body').removeClass('overflow-hidden');
}
function hideHeader() {
$('.cd-header').removeClass('is-fixed is-visible');
}
function hideMenu() {
$('.cd-header').removeClass('menu-is-open is-fixed is-visible');
$('.cd-menu-icon').removeClass('is-clicked');
}
function resizeWindow() {
var viewportWidth = $(window).width();
$(window).off('scroll'); // unbind scroll event
if (viewportWidth > 767) {
if ($('.cd-primary-nav').hasClass('is-visible')) {
if ($('.algolia__search-content').hasClass('algolia__search-content--active')) {
hideMenu();
$('.search-trigger').addClass('is-clicked');
$('.search-header').addClass('is-fixed');
} else {
hideMenu();
if (!$('.js-algolia__input').is(':focus')) {
$('.cd-primary-nav').removeClass('is-visible').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',function(){
removeOverflow();
});
$('.search-trigger').removeClass('is-clicked');
$('.search-header').removeClass('is-fixed');
} else {
$('.search-trigger').addClass('is-clicked');
$('.search-header').addClass('is-fixed');
}
}
} else {
hideHeader();
}
} else {
navSlide();
if ($('.cd-primary-nav').hasClass('is-visible')) {
$('.cd-header').addClass('menu-is-open');
$('.cd-menu-icon').addClass('is-clicked');
$('.search-trigger').removeClass('is-clicked');
$('.search-header').removeClass('is-fixed');
}
}
}

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;
}
});
});

Persistent header causes website to collapse in height

This is my code:
http://jsfiddle.net/KCb5z/8/embedded/result/
http://jsfiddle.net/KCb5z/8/
$(function () {
var $select = $('#select');
var $window = $(window);
var isFixed = false;
var init = $select.length ? $select.offset().top : 0;
$window.scroll(function () {
var currentScrollTop = $window.scrollTop();
if (currentScrollTop > init && isFixed === false) {
isFixed = true;
$select.css({
top: 0,
position: 'fixed'
});
} else if (currentScrollTop <= init && isFixed === true) {
isFixed = false;
$select.css('position', 'relative');
}
});
$(".nav").click(function (e) {
e.preventDefault();
var divId = $(this).attr('href');
$('body').animate({
scrollTop: $(divId).offset().top - $select.height()
}, 500);
});
});
The issue is when I scroll past the yellow bar it changes its CSS from relative to fixed. This means the website is now less tall and it drags all the content up, causing a kind of glitching effect.
It's almost like I need a containing div for the yellow bar which remains to keep that height, or insert some sort of div to keep the website height the same if the bar is docked or not.
Can anyone show me please how this might be implemented?
When the position is set to fixed, add padding to the top of the body to accommodate it. Similarly, remove the padding when the element is un-fixed:
if (currentScrollTop > init && isFixed === false) {
isFixed = true;
$select.css({
top: 0,
position: 'fixed'
});
$('body').css('padding-top', $select.height());
}
else if (currentScrollTop <= init && isFixed === true) {
isFixed = false;
$select.css('position', 'relative');
$('body').css('padding-top', 0);
}
Example fiddle
Note, the padding-top can be set on any element above the one to be fixed if required. I just used body as it was the most convenient for an example.

Categories