Sticky sidebar doesn't stop scrolling - javascript

I have a sticky sidebar on my page using the following script:
$(function() {
var offset = $("#sidebar").offset();
var topPadding = 15;
$(window).scroll(function() {
if ($(window).scrollTop() > offset.top) {
$("#sidebar").stop().animate({
marginTop: $(window).scrollTop() - offset.top + topPadding
});
} else {
$("#sidebar").stop().animate({
marginTop: 0
});
};
});
});
The problem is that it should stop scrolling when it reaches the Middle Block Div. At the moment it doesn't stop scrolling and it pushes all the rest of the content down. Is there a way to fix this?
- DEMO -
Thank you.

You need to get the position of .middle-block and stop the sidebar from scrolling at that point (minus the height of the sidebar).
Change your jQuery function to:
$(function() {
var offset = $("#sidebar").offset();
var mbOffset = $(".middle-block").offset();
var mbPos = mbOffset.top - $("#sidebar").outerHeight() - 30; /*30px extra space*/
var topPadding = 15;
$(window).scroll(function() {
if ($(window).scrollTop() > offset.top ) {
if( $(window).scrollTop() < mbPos ) {
$("#sidebar").stop().animate({
marginTop: $(window).scrollTop() - offset.top + topPadding
});
}
} else {
$("#sidebar").stop().animate({
marginTop: 0
});
};
});
});
Updated Pen

you have check if Sidebar has been moved to Middle Box, if so just stop the sidebar to animate.
like this :
$(function() {
var offset = $("#sidebar").offset();
var boxOffset = $(".middle-block").offset().top;
var sidebarHeight = parseInt($("#sidebar").outerHeight());
var topPadding = 15;
$(window).scroll(function() {
if ($(window).scrollTop() > offset.top) {
if(($(window).scrollTop()+sidebarHeight)<boxOffset){
$("#sidebar").stop().animate({
marginTop: $(window).scrollTop() - offset.top + topPadding
});
}
} else {
$("#sidebar").stop().animate({
marginTop: 0
});
};
});
});
check it live here: jsfiddle

Related

Do something when offset of div is smaler than fixed value

I want to fade the opacity of menu if it's offset to top of the window is smaler than 700px.
But I don't understand why this code doesn't work.
$(window).scroll(function() {
var offset = $(".navigation-top").offset();
var posY = offset.top - $(window).scrollTop();
if ($(posY) < 700) {
$('.navigation-top').animate({'opacity':'0.1'},500);
} else {
$('.navigation-top').animate({'opacity':'1'},500);
}
});
Thnaks to Carsten and Jeremy,
I ended up with this. But the .stop() is mantadory. Otherwise it works only with a extreme delay because of the mess of data from scrolling.
$(window).scroll(function() {
var offset = $(".navigation-top").offset();
var posY = offset.top - $(window).scrollTop();
if (posY < 700) {
$('.navigation-top').stop().animate({'opacity':'0.1'},500);
} else {
$('.navigation-top').stop().animate({'opacity':'1'},500);
}
});

debug lag of calculate margin top for Position fixed sidebar scrolling to bottom

I want to fix left sidebar on the responsive view.
I use Margin top (dependency with scroll position) for wrapper of sidebar!
that's work! but on the some browser it's slow motion (example: macbook pro retina 15" 2014 chrome Version 42)
jsfiddle
jQuery(function($){
var target = $('#fixed_sidebar .fixed');
var sidebarPosition = $(target).offset().top;
function calculatesidebar(){
var heightWindow = $(window).height();
var scrollPosition = $(document).scrollTop();
var sidebarHeight = target.outerHeight();
var positionOftarget = (sidebarPosition + sidebarHeight) - heightWindow;
var targetMargin = parseInt(target.css('marginTop'));
if (scrollPosition >= positionOftarget){
var margin = scrollPosition - positionOftarget;
target.css('marginTop', margin+'px');
}else{
target.css('marginTop', '0');
}
}
$( window ).scroll(function(){
calculatesidebar();
});
$( window ).resize(function() {
calculatesidebar();
});
});
i'm resolved in other way
jsfiddle
jQuery(function ($) {
function fixed_sidebar_bottom(wrapper, target) {
var left = $(wrapper).offset().left,
right = $(wrapper).offset().right,
top = $(wrapper).offset().top,
width = $(wrapper).width(),
target = $(target),
targetHeight = target.outerHeight(),
scrollPosition = $(document).scrollTop(),
windowHeight = $(window).height(),
windowWidth = $(window).width(),
hotSpot = (top + targetHeight) - windowHeight;
if (scrollPosition >= hotSpot) {
if (!target.attr('style')) {
target.css({'left': left, 'right': right, 'position': 'fixed', 'bottom': '0', 'width': width});
} else {
target.css({'left': left, 'right': right, 'width': width});
}
} else {
target.removeAttr("style");
}
}
$(window).scroll(function () {
fixed_sidebar_bottom('#fixed_sidebarLeft','#fixed_sidebarLeft_target');
});
$(window).resize(function () {
fixed_sidebar_bottom('#fixed_sidebarLeft','#fixed_sidebarLeft_target');
});
});

Jquery sticky menu not being caught by footer

Can anyone help me pinpoint the issue with my script please?
$(function () {
var top = $('#sidebar').offset().top - parseFloat($('#sidebar').css('marginTop').replace(/auto/, 0));
var footTop = $('#footer').offset().top - parseFloat($('#footer').css('marginTop').replace(/auto/, 0));
var maxY = footTop - $('#sidebar').outerHeight();
$(window).scroll(function (evt) {
var y = $(this).scrollTop();
if (y > 100) {
if (y < maxY) {
$('#sidebar').addClass('stickyside').removeAttr('style');
} else {
$('#sidebar').removeClass('stickyside').css({
position: 'absolute',
top: (maxY - top) + 'px'
});
}
} else {
$('#sidebar').removeClass('stickyside');
}
});
});
Live site here - https://tregothnan.co.uk/tea-herbal-infusions/
Sticky sidenav is spilling over the footer div and no matter what I try I can't get it to work. It works fine in my jsfiddle prototype.
The problem is that you are forgetting the margin-top of your sidebar in your calculation:
var maxY = footTop - $('#sidebar').outerHeight() - 68;
In your Prototype JSFiddle the sidebar just happened to have no margin-top.
On a sidenote: you may want to cache your selectors to improve performance. If you use the same selector more than once, for example $("#sidebar"), put it in a variable:var sidebar = $("#sidebar");.
Ok - many thanks #dark-ashelin
ended up with this - bit of a hack but it works.
$(function () {
var sidebar = $("#sidebar");
var top = $('#sidebar').offset().top - parseFloat($('#sidebar').css('marginTop').replace(/auto/, 0));
var footTop = $('#footer').offset().top - parseFloat($('#footer').css('marginTop').replace(/auto/, 0))-60;
var maxY = footTop - $('#sidebar').outerHeight() - 85;
$(window).scroll(function (evt) {
var y = $(this).scrollTop();
if (y > 100) {
if (y < maxY) {
$('#sidebar').addClass('stickyside').removeAttr('style');
} else {
$('#sidebar').removeClass('stickyside').css({
position: 'absolute',
top: (maxY + 50) + 'px'
});
}
} else {
$('#sidebar').removeClass('stickyside');
}
});
});

how to set speed following sidebar

I am using a sidebar which automatically scrolls up and down when scrolling the site. I am using this script for it:
$(function() {
var offset = $("#sidebar").offset();
var topPadding = 15;
$(window).scroll(function() {
if ($(window).scrollTop() > offset.top) {
$("#sidebar").stop().animate({
marginTop: $(window).scrollTop() - offset.top + topPadding
});
} else {
$("#sidebar").stop().animate({
marginTop: 0
});
};
});
});
But the automatically scrolling is a little bit fast. How can I set the speed of the up an down scrolling of the sidebar?
Assuming you're using jQuery, you can set the speed of the animation using "duration". It's a bit tricky to know if it works without the full HTML, but try this:
$(function() {
var offset = $("#sidebar").offset();
var topPadding = 15;
$(window).scroll(function() {
if ($(window).scrollTop() > offset.top) {
$("#sidebar").stop().animate({
marginTop: $(window).scrollTop() - offset.top + topPadding
},{
duration: 1000
});
} else {
$("#sidebar").stop().animate({
marginTop: 0
},{
duration: 5000
});
};
});
});
Source: http://api.jquery.com/animate/

Fixed header navigation and scrollTo() next/previous elements

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

Categories