Let's get straight to it: When the user scrolls x amount, I want the sidebar to begin to move.. Now, once the sidebar reaches its' end, I want it to stay fixed and scroll to the footer. Here's what I got.
http://jsfiddle.net/Ajp44/
Here's my 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);
}
});
});
For some reason JSfiddle isn't displaying what the Javascript is doing, but if you run it on your PC you can see. Whenever the user scrolls passed the ending of the sidebar, the sidebar doesn't scroll down with them like it is suppose to, instead, it jumps of to the right side of the page...
So my question is this: how do I stop the sidebar from jumping to the side of the page, and keep it within the restraints of the parent DIV?
Cheers!
Don't do right : 0 in your stick class. In fixed elements, the position attributes are relative to the viewport.
https://developer.mozilla.org/en-US/docs/Web/CSS/position#Fixed_positioning
Related
So I'm trying to get this element to scroll which it does but I'd like it to stop scrolling before the footer.
At the moment I have this but the pages don't have the same length so the >= 17900 is not a good solution for me.
$(window).scroll(function (event) {
var windowTop = $(this).scrollTop();
if (windowTop >= 17900) {
$(".product-form__item--quantity").addClass("non-fixed");
$(".product-form__item--submit").addClass("non-fixed");
$("#ProductPhotoImg").addClass("non-fixed");
$("#option_total").addClass("non-fixed");
$(".product-single__title").addClass("non-fixed");
$(".product-form__item--quantity").removeClass("change");
$(".product-form__item--submit").removeClass("change");
$("#ProductPhotoImg").removeClass("change");
$("#option_total").removeClass("change-option");
$(".product-single__title").removeClass("change");
} else {
//console.log('a');
$(".product-form__item--quantity").removeClass("non-fixed");
$(".product-form__item--submit").removeClass("non-fixed");
$("#ProductPhotoImg").removeClass("non-fixed");
$("#option_total").removeClass("non-fixed");
$(".product-single__title").removeClass("non-fixed");
}
});
Thanks for the help
You have more issues than only finding the footer's position here...
First is to find the position of the footer instead of hardcoding a value.
Okay...
Second is that you constantly add and remove classes on scroll.
This sure isn't the desired effect.
The scroll event fires like a dozen times or more on a single mouse wheel spin.
Third is that you force jQuery to lookup for elements, as #Taplar mentionned in comments, each times the script executes (Which is real bad if the script execute constantly!!). This is bad... And unuseful, since this those elements don't change.
So I modified your script... Almost completely :
;)
// Define an element collection ONCE.
var elementsList = $(".product-form__item--quantity, .product-form__item--submit, #ProductPhotoImg, #option_total, .product-single__title");
// Find the footer's position.
var footerPosition = $("#footer").offset().top;
// Set a flag to prevent the the script action when already done.
var footerVisible = false;
$(window).scroll(function (event) {
// How many pixels scrolled + viewport height = position of the last pixel at the bottom of the viewport relative to the document's top.
var viewportBottom = $(this).scrollTop() + $( window ).height();
if (viewportBottom >= footerPosition) {
if(!footerVisible){
// Will update classes on the element in the elementslist collection on user scroll enought to show the footer in viewport.
elementsList.addClass("non-fixed").removeClass("change change-option");
// Set a flag
footerVisible = true;
}
} else {
if(footerVisible){
// Will update classes on the element in the elementslist collection on user scroll from a "visible footer" to a footer below the viewport.
// In other words, You don't want to do it CONSTANTLY except when the footer is visible and dissapears due to user scroll up.
elementsList.removeClass("non-fixed");
// reset the flag.
footerVisible = false;
}
}
});
I have a sticky sidebar that when you scroll becomes fixed when the bottom of the sidebar is in view.
If the sidebar exceeds the length of the page as it does in this demo all works fine when you scroll and is exactly what you would expect.
However if the sidebar is shorter than the window height as in this demo, it seems to be jumping when you scroll and I can't work out how to get it to stop jumping and to be smooth. In other words it should only be fixed when the base of the sidebar hits the base of the window.
I'm not great with jQuery so any help would be greatly appreciated.
$(function () {
if ($('.leftsidebar').offset()!=null) {
var top = $('.leftsidebar').offset().top - parseFloat($('.leftsidebar').css('margin-top').replace(/auto/, 0));
var height = $('.leftsidebar').height();
var winHeight = $(window).height();
var footerTop = $('#footer').offset().top - parseFloat($('#footer').css('margin-top').replace(/auto/, 0));
var gap = 7;
$(window).scroll(function (event) {
// what the y position of the scroll is
var y = $(this).scrollTop();
// whether that's below the form
if (y+winHeight >= top+ height+gap && y+winHeight<=footerTop) {
// if so, ad the fixed class
$('.leftsidebar').addClass('leftsidebarfixed').css('top', winHeight-height-gap +'px');
}
else if (y+winHeight>footerTop) {
// if so, ad the fixed class
$('.leftsidebar').addClass('leftsidebarfixed').css('top', footerTop-height-y-gap + 'px');
}
else {
// otherwise remove it
$('.leftsidebar').removeClass('leftsidebarfixed').css('top', '0px');
}
});
}
});
Is it possible to combine the two instances? So if its shorter stay relative till the sidebar reaches the bottom, then act as it is now if the sidebar is longer?
The code works just as intended. This is actually a conceptual problem.
Picture how it would work first. The way you described it working seems to be exactly how it's working in your demo. When the sidebar is longer than the page, the scrolling page reaches the bottom of the sidebar before the leftsidebarfixed is added. That would be impossible with a shorter sidebar.
You may want to consider fixing the sidebar to the top, instead of the bottom (as most websites with sticky sidebars do) or having a taller header, so that the sidebar starts at the bottom.
I'm currently trying to get a div container to slide in from one side once the user has scrolled down a certain amount of px and disappear after the user has scrolled down another set amount of px.
This page has what I want to do - http://2014.igem.org/Team:CU-Boulder
If anyone can help me, I'd really appreciate it.
To get user's scroll data you can use scrollTop() jQuery method.
Description: Get the current vertical position of the scroll bar for
the first element in the set of matched elements or set the vertical
position of the scroll bar for every matched element.
For example:
$(window).scroll(function() {
var currentHeight = $(window).scrollTop();
if (currentHeight > 200) {
// some action
}
if (currentHeight > 300) {
// another action
}
});
You might be interested looking at this WOW plugin, or at this scrollrevealjs.
I love that this code works, but I cannot, for anything, wrap my head around WHY it's working?
Here is the jfidddle
Here is the code:
jQuery(document).ready(function($) {
clone = $('div').clone();
$('div').after(clone);
$('div:last').hide();
offset = $('div:first').offset();
var fromtop = offset.top;
$(document).scroll(function() {
doc = $(this);
dist = $(this).scrollTop();
if (dist >= fromtop) {
$('div:last').show();
$('div:first').css({
'position': 'fixed'
});
} else {
$('div:first').css({
'position': 'static'
});
$('div:last').hide();
}
});
});
I guess I am not understanding how scrolltop and offset are interacting or what they REALLY are, as in their true positions on the page. The code says if ScrollTop (the scrollbar position?) is higher than the value of the div's offsettop , then make the div sticky. But if ScrollTop is the position of the scrollbar, isn't it true that sometimes the scroll bar position could be lower than the div's position BEFORE the div is at the top of the page? What is it about being at the top of the page (offsettop of 0?)--and only at the top of the page, never before-- that makes offsettop a smaller value than scrolltop?
Really confused, and I don't want to just copy the code without understanding what it's really doing.
scroll Top is actually how many pixels 'up' the page has moved (or how many pixels you have moved down the page)
Basically all that happens is the .offset sees how far down the page (from the top of the page) the 'sticky' menu is
When you scroll to that point the bar becomes fixed (which is basically relative to the window instead of the document)
When you scroll back up it just switches back to being positioned in the document.
For clarity
.offset = 200px say - this is how far down the document the sticky menu is
.scrollTop - is 0 when the page loads
When you scroll down the page 201px
.scrollTop > .offSet -> so make the bar fixed (remember fixed is relative to the window - not the document)
If you scroll back up the process is reversed.
It's actually very simple. Let me try if I can make it a bit clear to you:
Whenever you want something (let's say some div) to get fixed on top as you scroll down, you need two things:
You need the current vertical position of your div. And you calculate that by using offset().top
You need to track how much user has scrolled. And you calculate that by using scrollTop()
So in your case, if the current position of your div is top: 100, then as soon as your scrollbar reaches the number 101, your div will get the class of .fixed
By default, the scrollbar vertical position is 0 when the page loads.
I want to make my social sidebar in the left side scrolling or hide when it will reach to the footer part. So how can I do it please ? Thanks.
If you want to make the floating social bar on the left to hide when an element i.e. the footer, is visible within the viewport of the browser, you can compare the top offset of the element with the bottom position of the browser's viewport. For example,
$(document).ready(function(){
$(document).scroll(function(){
var footerSelector = '#wrapper-12';
var socialBarSelector = '.pw-float-left';
var bottomViewPort = $(window).scrollTop()+$(window).height();
var footerTop = $(footerSelector ).offset().top;
if( bottomViewPort>=footerTop){
$(socialBarSelector).fadeOut();
}else{
$(socialBarSelector).fadeIn();
}
});
});