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
Related
I want to display the popup on the top of element if there is no proper space on the top. Currently it hides inside the window as seen in the image below:
I can update the top position but I only want when there is no proper space otherwise it is ok.
Please let me know how to determine if the clicked position in near window edges.
JSFiddle Link :http://jsfiddle.net/g4g4negf/
Code I am using to get the position:
$(document).ready( function() {
$('.clickme').on('click', function(e) {
$('#popup').offset({ top: e.pageY, left: e.pageX}).fadeIn();
});
Check out this JSFiddle
To check if clicked position is near window edge, you have to get window's height ($(window).height()) and scroll position (window.pageYOffset). By adding these two values, you can find the scrolled position of the window. Then compare this sum with e.pageY+$("#popup").height() (this is the sum of the clicked position's height and the popup's height). If the latter is less than the former, it means the popup can be shown. If (e.pageY+$("#popup").height())>($(window).height()+window.pageYOffset) it means the popup will overflow the window's bottom border, then its top offset should be changed to e.pageY-$('#popup').height().
Here is the complete function:
$('.clickme').on('click', function(e) {
var h;
if((e.pageY+$('#popup').height())<($(window).height()+window.pageYOffset)) h=e.pageY;
else h=e.pageY-$('#popup').height();
$('#popup').offset({ top: h, left: e.pageX}).fadeIn();
});
Considering your popup height is 100px, you can try this...
$(document).ready( function() {
var h = window.innerHeight;
$('.clickme').on('click', function(e) {
alert(h + ", " + e.pageY);
if( h - e.pageY < 125) {
$('#popup').offset({ top: h-125, left: e.pageX}).fadeIn();
}
else {
$('#popup').offset({ top: e.pageY, left: e.pageX}).fadeIn();
}
});
});
I have a submenu that is scrolls with the site using position:fixed; I am using jQuery to calculate where it should sit as it's outside of the main content of the site.
It's working fine except for when I resize the browser window; it then disappears from view. Looking at the code in dev tools, it's still there and should be visible.
Perhaps there is something wrong with my script? Your help would be very much appreciated.
jQuery(document).ready(function() {
// Sub Menu Placement
calculation();
jQuery(window).resize(calculation);
function calculation() {
var location = jQuery(".page-content-section .page-content-section-inner").offset();
var locationTop = jQuery(".header").offset();
var left = location.left;
left = left - 0;
var top = locationTop.top;
top = top + jQuery('.header').height();
jQuery("#submenu").css({
//'position': 'absolute',
'position' : 'fixed',
'top': top + 'px',
'left': left + 'px'
});
}
});
I figured out the issue:
I changed this line:
top = top + jQuery('.header').height();
to this:
top = jQuery('.header').height();
I have a question but I actually do not know how to ask.
I am trying to make a navigation bar stick on top when pass a point smoothly.
My reference is this -> http://blog.yjl.im/2010/01/stick-div-at-top-after-scrolling.html
My problem is when I use IE or Chrome to check it, there is a "blink" effect.
It is more like the scroll function will finish process after scroll over the point. So the things(HTML) after Nav will go on the top of the Nav on 0.1 ~ 0.3 secs then scroll function will finish process. Even through is short but it is visualize-able when the HTML over the nav.
However, If I use Firefox to check it, there is no such blink effect.....
May I ask what is the problem here I got?? What Should I check about??
My setting is a Anchor right before the Nav, Nav z-index = 99, and inside of the scroll function is below.
$(this).scrollTop() > $(anchor).offset().top
? nav.addClass('sticky')
: nav.removeClass('sticky')
jQuery(document).ready(function($) {
var my_nav = $('.navbar-sticky');
// grab the initial top offset of the navigation
var sticky_navigation_offset_top = my_nav.offset().top;
// our function that decides weather the navigation bar should have "fixed" css position or not.
var sticky_navigation = function(){
var scroll_top = $(window).scrollTop(); // our current vertical position from the top
// if we've scrolled more than the navigation, change its position to fixed to stick to top, otherwise change it back to relative
if (scroll_top > sticky_navigation_offset_top) {
my_nav.addClass( 'stick' );
} else {
my_nav.removeClass( 'stick' );
}
};
var initio_parallax_animation = function() {
$('.parallax').each( function(i, obj) {
var speed = $(this).attr('parallax-speed');
if( speed ) {
var background_pos = '-' + (window.pageYOffset / speed) + "px";
$(this).css( 'background-position', 'center ' + background_pos );
}
});
}
// run our function on load
sticky_navigation();
// and run it again every time you scroll
$(window).scroll(function() {
sticky_navigation();
initio_parallax_animation();
});
});
/-----------------------------------------------------------------------------------/
EDIT: I do NOT want to use fixed CSS positioning. It's at the bottom of the viewport
without scrolling, however I want it to follow when it gets to the top.
/-----------------------------------------------------------------------------------/
I'm making a Squeeze Page with a MASSIVE sidebar. It's got tons of testimonials and facts and pictures and stuff. However, I have a button near the top I want to follow the user down the page as they scroll. Shouldn't be too hard right?
I've got this script - which starts dragging the .followme when it hits the top of the page. However - it also pushed down all the divs beneath it. Can I tell it to target JUST .follow and no affect the divs below it?
<script type="text/javascript">
var documentHeight = 0;
var topPadding = 15;
$(function() {
var offset = $(".followme").offset();
documentHeight = $(document).height();
$(window).scroll(function() {
var sideBarHeight = $(".followme").height();
if ($(window).scrollTop() > offset.top) {
var newPosition = ($(window).scrollTop() - offset.top) + topPadding;
var maxPosition = documentHeight - (sideBarHeight + 100);
if (newPosition > maxPosition) {
newPosition = maxPosition;
}
$(".followme").stop().animate({
marginTop: newPosition
});
} else {
$(".followme").stop().animate({
marginTop: 0
});
};
});
});
You have an easier option which doesn't require any JS\jQuery at all.
.followme {
position: fixed;
height: 30px;
width: 30px;
background-color: #FF0000;
top: 48%;
left: 0;
}
This will never affect any of the other elements of the page and doesn't require any scripting at all. Now if you need the element (followme) to for example show at a certain scroll % or any other interactivity you might think of, then you will be needing to think more creatively. But if the problem is just to let the element follow your scrolling then the above should be a good and clean solution.
Example code:
http://jsfiddle.net/bhpgC/
I need solution to emulate fixed position, but relative parent div, not whole viewport. JS solutions are laggy. I need fixed related parent container, because if window has small height, div with fixed position enters into footer zone.
Example
Another approach re your update.
Try giving the fixed div z-index: 10;
And the footer div position: relative; z-index: 11
That should make the footer overlap the fixed div.
then it's not an issue of position:fixed, maybe you could just define a min-height to your body (or on the main wrapper if any) to avoid the short page problem
I have combined css and js:
$(document).ready(function () {
var $sidebar = $(".register-box"),
$window = $(window),
$content = $("#content"),
docHeight = $(document).height();
var entered = false;
$window.scroll(function () {
if ($window.height() < 795 && docHeight - $window.scrollTop() < 785) {
entered = true;
var pos = $sidebar.offset();
$sidebar.css('position', 'absolute').css('top', ($content.height() - ($sidebar.height() + 40)) + 'px');
}
else {
if (entered) {
entered = false;
$sidebar.css({
top: "",
left: "",
position: "fixed"
});
}
}
});
});
Code is not final, and numbers are hard coded, but it works, smooth enough.