I'm creating an onepager and need my click-to-scroll script to keep a distance from the anchor section and the top of the page in exactly the size of my fixed navigation bar, to have a clean connect when a link is clicked.
I used already a second anchor with a code which looked like this:
.anchor-1 {
display: block;
position: absolute;
top: -77px;
visibility: hidden;
}
But if I use it, my script will not work as it should.
This is my click-to-scroll script with the 'nav-height' included on the sections. Links are active on the perfect position when I'm scolling by myself, but on clicking it's not moving to the perfect position.
var sections = $('section')
, nav = $('nav')
, nav_height = nav.outerHeight();
$(window).on('scroll', function () {
var cur_pos = $(this).scrollTop();
sections.each(function() {
var top = $(this).offset().top - nav_height,
bottom = top + $(this).outerHeight();
if (cur_pos >= top && cur_pos <= bottom) {
nav.find('a').removeClass('active');
sections.removeClass('active');
$(this).addClass('active');
nav.find('a[href="#'+$(this).attr('id')+'"]').addClass('active');
}
});
});
I need to add a nav_height to the scroll position instead of having sections scrolled all the way to the top, to have a perfect distance from the top.
Related
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
I'm trying to have a submenu stay at the top of the page while scrolling once it reaches the top during scrolling. Here is what I have so far:
$(window).scroll(function () {
if ($(window).scrollTop() > 175) {
$('#location_menu').css('position', 'fixed').css('top','0px').css('z-index','1000');
$('.first').css('padding-top','415');}
else {
$('#location_menu').css('position', 'relative').css('z-index','1');
}});
The issue I'm having is that the scroll is not smooth and once the element changes from position:relative to position:fixed the content seems to jump/skip up about 415px which is the same height as the submenu.
Here is the css:
<div id="location_menu" >submenu content
</div>
<div id="content" class="location_detail first">content beneath submenu
</div>
I've added the line for .first to have a padding-top of 415px when the page is crolling and reaches within 175px of the top of the page .css('padding-top','415') this doesn't actually seem to be doing anything though. There is no change, so I assume I have executed it incorrectly.
Should I use a different scrolling function then I have listed above?
Here is what I ended up using to fix my problem, based off the code from #Danko :
$(window).scroll(function () {
var $conten = $('.first'),
$menu = $('#location_menu')
scrollpos = $(window).scrollTop();
if (scrollpos >= 175) {
$conten.css('padding-top','365px');
$menu.css('position', 'fixed').css('top','0px').css('z-index','1000');
} else {
$conten.css('padding-top','0');
$menu.css('position', 'fixed').css('position', 'relative').css('z-index','1');
}
});
Edit
Ok now that i understand the question, i did this demo http://codepen.io/anon/pen/BdkLf.
The function in fact is this:
$(window).scroll(function () {
var $menu = $('#location_menu'),
$conten = $('#content'),
scrollpos = $(window).scrollTop();
if (scrollpos >= 175) {
$menu.css( {
"top" : "0",
"position": "fixed",
});
$conten.css('top','375px' );
} else {
$menu.css( {
"position": "relative",
"top" : "175px",
});
$conten.css('top','175px');
}
});
Here 175 is equals to the initial distance from the top and 375 is the addition between the distance and the height of your menu
Right now I have it that if a user scrolls past the bottom of the side bar, then the sidebar turns to fixed and stays on the users page while they read the rest of the main content.
But now my fixed div is falling out into the footer. So, how can I stop it from falling out of the parent div and into the footer?
Here's a fiddle of what's going on: http://jsfiddle.net/95W8w/
All the code is in jsFiddle, but since SO requires I put code here if I have a jsFiddle include.
JavaScript:
$(document).ready(function() {
// Cache selectors for faster performance.
var $window = $(window),
$sidebar = $('#anchor'),
$sidebarAnchor = $('#right');
// Run this on scroll events.
$window.scroll(function() {
var window_top = $window.scrollTop();
var div_top = $sidebarAnchor.offset().top;
if (window_top > div_top) {
// Make the div sticky.
$sidebar.addClass('stick');
$sidebarAnchor.height($sidebar.height());
}
else {
// Unstick the div.
$sidebar.removeClass('stick');
$sidebarAnchor.height(0);
}
});
});
Change bottom to top in your .stick class definition to make the sidebar stick to the top instead of bottom.
.stick {position: fixed; top:0px;}
Im using Chris Coyier's Sticky Footer example to add a footer to my webpage.
It works great!
However, I am wondering how I can adjust the code so the footer sits at the bottom of the screen -- not the webpage.
So for example when it first loads rests at the footer of my screen - but when I begin to scroll down it adjusts itself and locks itself down at the bottom of the page.
How can I keep it at the bottom of my screen?
Ive tried tweaking the last 2 lines of the emample:
$(window)
.scroll(positionFooter)
.resize(positionFooter)
But not getting too far...
hope this works for you http://jsfiddle.net/8YWHn/
the css
.fixed {
position:fixed;
bottom:0px;
-webkit-backface-visibility:hidden;
}
the js
var footerHeight = 0,
footerTop = 0,
$footer = $("footer");
positionFooter();
function positionFooter() {
footerHeight = $footer.height();
footerTop = ($(window).scrollTop()+$(window).height()-footerHeight)+"px";
if ( ($(document.body).height()+footerHeight) < $(window).height()) {
$footer.css({
position: "absolute"
}).animate({
top: footerTop
})
} else {
$footer.addClass('fixed');
}
}
$(window)
.scroll(positionFooter)
.resize(positionFooter)
Another way to do this that works for me is simply replace the line in the javascript:
position: "static"
with:
position: "fixed"
Following a tutorial from Andrew Henderson's blog, I have the following jQuery script:
$(document).ready(function() {
var stickyTop = $('.sticky').offset().top;
$(window).scroll(function() {
var windowTop = $(window).scrollTop();
if (top < windowTop) {
$('.sticky').css({ position: 'fixed', top: '10px' });
}
else {
$('.sticky').css('position','static');
}
});
});
This works fine when my page has one sticky sidebar. However, when my page has multiple sticky sidebars, all of them scroll when the first sidebar starts to stick.
Is there a way that I can modify the script to only make the sidebars that are in the range start to stick?