Fixed Navigation Bar with two different states - javascript

What I want to do is have a fixed navigation bar that is 10px from the top of the window unless it is within the first 200px of the document, then I want it to be 200px from the top ...
So basically I want a navigation bar that is 200px from the top to start off with, but when the user scrolls down 190px the navigation bar scrolls, staying always 10px from the top of the window.

You first listen to the scroll event of the window, and then use the scroll value to know what state to apply to you element. Example with jQuery :
var fixed = false, limit = 50;
$(window).scroll(function()
{
if (window.scrollTop < 50 && fixed)
{
$("#header").css({ position: "relative" });
fixed = false;
}
else if (window.scrollTop > 50 && !fixed)
{
$("#header").css({ position: "fixed" });
fixed = true;
}
});
Also related to this post for code example

Related

javascript issue with fixed position side menu

I'm building a website with a sidebar that, once the user scrolls past a certain point it becomes fixed on the site. This code works fine.
The issue that I am coming into is that the sidebar is overlapping the footer when the user scrolls to the bottom of the page. I wrote code to detect when the bottom of the sidebar hits the same position as it's containing element - when that happens I am taking the position of the bottom of the containing element and subtract the height of the sidebar element and using that number to give the sidebar it's new "top" (while also changing the position to "absolute").
This is where I am running into the issue - once the sidebar is overtop of the footer as the user scrolls the code that is getting called alternates between the normal "fixed" position code and the "absolute" positioned code giving it this flickering effect.
For the life of me I can't figure out why the "fixed" code keeps getting called.
Here is the code:
( function( $ ) {
var sidebar_pos = $('#secondary')[0].getBoundingClientRect();
var pos_top = sidebar_pos.top + window.scrollY; //need this to get the pos of TOP in the browser - NOT the viewport
var main_pos = $('.main-content')[0].getBoundingClientRect();
var main_bottom = main_pos.bottom + window.scrollY;
var stop_pos;
var i = 0;
$(window).scroll(function(event){
var scroll = $(window).scrollTop();
var produce_pos = $('.produce')[0].getBoundingClientRect();
var pos_bottom = produce_pos.bottom + window.scrollY;
//console.log("scroll "+scroll);
//console.log("top " + pos_top);
console.log(main_bottom);
console.log('bottom ' + pos_bottom);
if( scroll >= pos_top){
if ( pos_bottom >= main_bottom ){
//if the sidebar would end up overlapping the footer
if(i == 0){
//only need to set this once, not on every scroll
stop_pos = main_bottom - $('#secondary').height() ;
}
$('#secondary').removeClass('hover').css({
position: 'absolute',
margin:0,
left: sidebar_pos.left,
top: stop_pos
});
i++;
} else {
$('#secondary').addClass('hover').css({
position: 'fixed',
left: sidebar_pos.left,
marginTop: '1.5em',
top: 20
});
setTimeout(() => {
$('*[data-widget="comet"]').addClass('active');
}, 5000);
setTimeout(() => {
$('*[data-widget="produce"]').addClass('active');
}, 7000);
}
} else if( scroll < pos_top && $('#secondary').hasClass('hover') ){ //if user scrolls up past original pos of sidebar, remove effects
$('#secondary').removeClass('hover').css({
position: 'relative',
left: 'auto',
top: 'auto'
});
i = 0;
}
});
}( jQuery ) );
I also have a codepen of the script in action.
https://codepen.io/antlaur00/pen/ExyrgYR
Any help is much appreciated! Thanks!
Well its pretty simple, just add Z-index property to your footer CSS, that way it will always overlap your sidebar .
You can refer to this article regarding the z-index property
https://www.w3schools.com/cssref/pr_pos_z-index.asp

Scroll div horizontally instead of page, then scroll page

it isn't a duplicate as I've read the others question but everyone assume that the scroll is vertical, while i need this for horizontal scroll.
What i'm trying to do is to scroll a div, placed somewhere in a page, when it reach the center of the screen or it is almost visible, then when it end its scroll i need to continue the page scrolll.
Actually i have a "slider" like this: JSFIDDLE
Actually, I can get an advise when the element is visible on the page after scrolling, but I don't know how to disable vertical scroll, scroll my div, and then scroll page again. The important thing is that the div scroll how much i continue the scrolling (intended with mouse, keyboard and maybe touch, it will be awesome)
function testInView($el){
var wTop = $(window).scrollTop();
var wBot = wTop + $(window).height();
var eTop = $el.offset().top;
var eBot = eTop + $el.height()+50;
return ((eBot <= wBot) && (eTop >= wTop));
}
function setInView(){
$(".slider-wrapper").each(function(){
var $zis = $(this);
$zis.removeClass("inview");
if(testInView($zis)){
alert("eccolo");
}
});
}
$(document).scroll(function(){
setInView();
});
$(document).resize(function(){
setInView();
});
$(document).ready(function(){
setInView();
});
If you want to disable vertical scrolling then just set overflow-y: hidden on body element
body {
overflow-y: hidden;
}

Detect if a page has loaded at the top, or somewhere down the page, with Javascript

Most webpages load so that you're at the top of the page by default. If you're halfway down a page, and click Refresh/Reload, most browsers will reload the page, but you'll still be wherever you were on that page.
If you have sticky navigation that relies on scroll position, this means that your navigation may not appear correctly until you scroll.
I have tried to get the value by using something like this in jQuery:
var h_offset = $('.h').position();
alert(h_offset.top);
However, this will report 0 since my .h div is positioned absolutely to the top of the browser, even if I'm scrolled halfway down the page.
Is there a way to get the distance between the top of the document and where the .h is as far as how far down the page you've scrolled?
You can use document.documentElement.scrollTop to check the position of the Y scroll axis of the page after page load.
You can use jQuery .offset() to get the offset top and left of an absolute positioned element after page load.
$(window).on('load', function() {
let scrollTop = document.documentElement.scrollTop;
console.log('scrollTop', scrollTop);
// Get the offset (left, top) of #abs element after page load
let { left, top } = $('#abs').offset();
console.log('#abs top', top);
if (scrollTop === 0) {
// We are at the top
} else {
// The page is scrolled down by scrollTop pixels
// Use scrollTop and left to calc new scroll value or set it to 0
// You can use this to scroll the page at the top after each load
setTimeout(() => {
window.scrollTo(0, 0);
}, 50);
}
});
$(window).on('load', function() {
let scrollTop = document.documentElement.scrollTop;
console.log('scrollTop', scrollTop);
let { left, top } = $('#abs').offset();
console.log('#abs top', top);
if (scrollTop === 0) {
// We are at the top
} else {
// The page is scrolled down by scrollTop pixels
// You can use this to scroll the page at the top after each load
setTimeout(() => {
window.scrollTo(0, 0);
}, 50);
}
});
#abs {
position: absolute;
left: 100px;
top: 2000px;
width: 20px;
height: 20px;
background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>Top of the page</h1>
<div style="margin-bottom: 2000px"></div>
<h1>Bottom of the page</h1>
<div id="abs"></div>

How can I fix a div under my original header if it changes height when scrolling?

I created an additional menu bar (.secondnav) that I want to place right below the original header (#headAnnouncementWrapper) in a website. The problem is, when scrolling, the header's height changes when going from relative position to fixed at the top, and also when on mobile.
I've been trying with this:
var scrolled = 78;
var headHeight = $('#headerAnnouncementWrapper').height();
$(window).scroll(function() {
if ($(window).scrollTop() > scrolled) {
$('.secondnav').css('position', 'fixed');
$('.secondnav').css('top', headHeight);
} else {
$('.secondnav').css('position', 'relative'),
$('.secondnav').css('top', headHeight);
}
});
But I don't know how I should be calculating the headHeight variable so it changes when the height changes, and how to use that result as the top value for the .secondnav's css.
Check the height of the main header inside the scroll event. Each time the scroll event triggers, it will recheck the height. Then, the next line will adjust the top margin of the lower header to match the height of the upper header. Top-margin here replaces your position method.
var scrolled = 78;
$(window).scroll(function() {
var headHeight = $('#headerAnnouncementWrapper').height();
$('.secondnav').css('marginTop', headHeight);
if ($(window).scrollTop() > scrolled) {
$('.secondnav').css('position', 'fixed');
} else {
$('.secondnav').css('position', 'relative'),
}
});

Div follow scroll issue: scroll jump back to window top

I've found and adapted this method to have my div follow down the scroll bar, only after a certain point is reached:
$.fn.followFrom = function (pos, left_fixed, left_absolute) {
var $this = this,
$window = $(window);
$window.scroll(function (e) {
if ($window.scrollTop() < pos) {
$this.css({ // no move
position: 'absolute',
top: 400,
left: left_absolute
});
} else { // move
$this.css({
position: 'fixed',
top: 220,
left: left_fixed
});
}
});
};
Strangely (or not?), it works only when my div has content to its right.
But when it's the bottom element on the screen, then when scrolling and position is reached, hop the scroll bar jumps back to the top, which is a very frustrating user experience.
The context is a search page, where I have a map in my moving div on the left, and the search results on the right. So I want that when scrolling down the results, the map stays visible on the left.
So it works only when there are results AND the results height is bigger than the map's height. But as soon as the results' height gets shorter, then I get the jump.
Thanks

Categories