How to stop a fixed sidebar from going in the footer? - javascript

I'm building a website. http://check.topicwine.com
Have a look to see my work.
I want to make a static sidebar. I'm using the code:
$(function() {
var offset = $("#ad-wrapper").offset();
var topPadding = 60;
$(window).scroll(function() {
if ($(window).scrollTop() > offset.top) {
$("#ad-wrapper").stop().animate({
marginTop: $(window).scrollTop() - offset.top + topPadding
});
} else {
$("#ad-wrapper").stop().animate({
marginTop: 0
});
};
});
});
The sidebar comes along, but it also goes where it shouldn't. I mean, it enters the footer as well. Rather, it overlaps the footer.
I want it to stop next to the grid.
Thanks, in advance. :)

Add overflow:hidden to div#content. This way we will get the proper height of the content div.
Now $('#content').height() + $('#content').offset().top is the maximum distance the sidebar should move. Which means, the sidebar's offset.top + height should not go more than this.
Add this check in your scroll handler

Set a limit for the top margin, since the sidebar can't go past the $('#main') element.
$(function() {
var offset = $("#ad-wrapper").offset();
var topPadding = 60;
$(window).scroll(function() {
var scrollTop = $(window).scrollTop(); // Store this for convenience
if (scrollTop > offset.top) {
var newMarginTop = scrollTop - offset.top + topPadding;
// The sidebar can only go so far!
var marginLimit = $('#main').height() + $('#main').offset().top - offset.top - $("#ad-wrapper").height();
if (newMarginTop > marginLimit)
newMarginTop = marginLimit;
$("#ad-wrapper").stop().animate({
marginTop: newMarginTop
});
} else {
$("#ad-wrapper").stop().animate({
marginTop: 0
});
}
});
});

Related

jQuery - Following div on Scroll that stops at specified top or bottom margin

I have this jsfiddle: https://jsfiddle.net/3ncyxnzt/
It currently works well as far as always stopping at a specified margin from the top of the page, but I'd like to make it also stop at the bottom, before it goes under/over the footer. Any ideas on how to make that moving red box stop right above the green footer? The height of the footer is 1000px, so I'd somehow need to set the moving box to stop at 1000px from the bottom.
Here's the code I have so far:
(function(jQuery) {
var element = jQuery('.move'),
originalY = element.offset().top;
var topMargin = 110;
element.css('position', 'relative');
jQuery(window).on('scroll', function(event) {
var scrollTop = $(window).scrollTop();
element.stop(false, false).animate({
top: scrollTop < originalY
? 0
: scrollTop - originalY + topMargin
}, 200);
});
})(jQuery);
I modified following line by adding static value 290 and it reached to bottom.
scrollTop - originalY + topMargin + 290
Is this what you trying to achive?
(function(jQuery) {
var element = $('.move'),
originalY = element.offset().top,
otherDiv = 1000,
staticHeight = $('.other-div').height()-$(element).height(); // Fixed number to stop the move-element before the footer
var topMargin = 110;
jQuery(window).on('scroll', function(event) {
var offset = element.offset().top;
var scrollTop = $(window).scrollTop();
// Check if the move-block gets under the footerblock
if(scrollTop < otherDiv){
element.stop(false, false).animate({
top: scrollTop - originalY + topMargin
}, 200);
}else{
element.stop(false, false).animate({
top: staticHeight //If so, make sure it gets on top of the footerblock staticly
}, 200);
}
});
})(jQuery);
I think you need an if/else statement to check if the block gets behind the height of the div called "other-div".
See the working example here: https://jsfiddle.net/crix/z578c9bo/
Hope it helps!

Fix div position between two heights

I have a div that I want to keep position: fixed when scrolling between two points.
For example, it should remain fixed only between the height of it's container div
I've done the following:
$window.scroll(function(e) {
pos = $('.container-element').height();
if ($window.scrollTop() > pos) {
$(scroll-element).css({
position: 'relative',
});
} else {
$(scroll-element).css({
position: 'fixed',
});
}
});
However, this doesn't stop the scroll-element from becoming relative on reaching the end of the container-element. What should I do to achieve the intended behavior?
EDIT:
JSFiddle: http://jsfiddle.net/09760d60/
I think You should remove fixed position when $(window).scrollTop() > containerHeight-childHeight
$(document).ready(function(){
$(window).scroll(function(e) {
containerHeight = $('.container-element').height();
childHeight = $(".scroll-element").height();
if ($(window).scrollTop() > containerHeight-childHeight) {
$('.scroll-element').removeClass('fixed');
} else {
$('.scroll-element').addClass('fixed');
}
});
});
Please check updated fiddle
http://jsfiddle.net/PrashantShirke/1u991v1j/
You should check the top and bottom bounds of your container, and compare it with the top and bottom bounds of your scroll element :
$(document).ready(function(){
$(window).scroll(function(e) {
containerTop = $('.container-element').offset().top;
containerBottom = $('.container-element').height()+$('.container-element').offset().top;
scrollEl = $('.scroll-element').height();
if ($(window).scrollTop() >= containerTop && $(window).scrollTop()+scrollEl <= containerBottom) {
$('.scroll-element').css({
"top":$(window).scrollTop()+"px"
});
}
});
});
Exemple
$(window).scrollTop() < containerTop: scroll element is at top of content
$(window).scrollTop()+scrollEl > containerBottom: bottom of scroll element is at bottom of content
If scroll element has to move, adjust its top property while being absolutelly positioned by CSS.
I think it would be more robust to check the bottoms of the container and window, not the heights of the container and child.
$(document).ready(function(){
var $window = $(window);
var $container = $('.container-element');
var $scroll = $('.scroll-element');
var containerBox = $container[0].getBoundingClientRect();
$window.scroll(function(e) {
var scrollBottom = $window.scrollTop() + $window.height();
var canSeeContainerBottom = scrollBottom > containerBox.bottom;
$scroll.css('position', canSeeContainerBottom ? 'relative' : 'fixed');
});
});
http://jsfiddle.net/bryandowning/09760d60/14/

Sticky sidebar scrolling lag and infinite scroll

I have a sidebar that scrolls down with the page. However, the sidebar seems to lag behind the scrolling of the page, ex. scroll down and sidebar shows up a few seconds later. Also, the sidebar will keep going down, making the page longer, and causing the footer to become inaccessible. What do I need to do to make the sidebar move with the scroll and for the sidebar to stop moving at the footer? Here is my jQuery code:
$(function() {
var $sidebar = $("aside"),
$window = $(window),
offset = $sidebar.offset(),
topPadding = 50;
$window.scroll(function() {
if ($window.scrollTop() > offset.top) {
$sidebar.stop().animate({
marginTop: $window.scrollTop() - offset.top + topPadding
});
} else {
$sidebar.stop().animate({
marginTop: 0
});
}
});
});
An example can be seen at http://meddiary.com/plans-pricing/. Fixing the code is welcomed but just pointing me in the right direction is the best.
Try solving it with pure CSS:
.affix {
position: fixed;
}
Or you can use an existing jQuery plugin like this one:
http://andrewhenderson.me/tutorial/jquery-sticky-sidebar/
This is how I fixed my issue:
if ($(window).width() > 767) {
var $sidebar = $("aside"),
$window = $(window),
offset = $sidebar.offset(),
topPadding = 50;
$window.scroll(function() {
if($window.scrollTop() > $('h3').offset().top) {
$sidebar.stop().css('marginTop', '680px');
} else if ($window.scrollTop() > offset.top) {
$sidebar.stop().animate({
marginTop: $window.scrollTop() - offset.top + topPadding
}, 100, function() {
});
} else {
$sidebar.stop().animate({
marginTop: 0
});
}
});
};
if ($(window).width() > 767) part keeps the sidebar from scrolling if the viewport is wider than 767px. if($window.scrollTop() > $('h3').offset().top) { $sidebar.stop().css('marginTop', '680px'); } part is for when the top of the viewport hits the desired element, h3, the scrolling stops. That part must be first because the else if statement is always true! Then I just reduced the animation time to stop the lagging.

Trigger function at specific window size

I have a div that follows the browser as it scrolls and is contained within another div.
The following function keeps my div in place and moving when the user scrolls:
$(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
});
};
});
});
This works pretty well, except when the browser height is less than 400px, then it gets buggy.
So I thought I'd include a simple line to get it to only run when the browser is >=400 as such:
if (window.innerHeight >= 400) {
$(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
});
};
});
});
}
This seems to work fine so long as the initial browser height is greater than 400px. If the browser window is resized from it's initial height, the code will still execute, which is counter to what I want.
Essentially, is there a way to dynamically track the browser size and only run this code when the height is larger than 400px and not run when less than 400px?
Thanks for any help!
Just move the check into your event handler:
$(function() {
var offset = $("#sidebar").offset();
var topPadding = 15;
$(window).scroll(function() {
if (window.innerHeight >= 400) { // <=== Moved it here
if ($(window).scrollTop() > offset.top) {
$("#sidebar").stop().animate({
marginTop: $(window).scrollTop() - offset.top + topPadding
});
} else {
$("#sidebar").stop().animate({
marginTop: 0
});
}
}
});
});
Now the check is done when you're processing the scroll event, rather than just once at the outset preventing the scroll from being hooked at all.
Separately, because you're doing this on the scroll event, which happens pretty often, I'd try to minimize the number of times you wrap or look up elements. Instead of doing it on every event, since window isn't going to change and I suspect your sidebar isn't going to change either, wrap/look them up once:
$(function() {
var offset = $("#sidebar").offset();
var topPadding = 15;
var sideBar = $("#sidebar");
var $window = $(window);
$window.scroll(function() {
if ($window.height() >= 400) { // <=== Moved it here
if ($window.scrollTop() > offset.top) {
sidebar.stop().animate({
marginTop: $window.scrollTop() - offset.top + topPadding
});
} else {
sidebar.stop().animate({
marginTop: 0
});
}
}
});
});
That also makes it reasonable to use jQuery's height function on window for cross-browser compatibility.
To track the browser width & height as it is being resized:
$(window).resize(function()
{
var viewportWidth = $(window).width();
var viewportHeight = $(window).height();
// More code here...
};
However, I think there is a better way to keep your div in place, one that does not involve Javascript. Have you tried using position:fixed?

Jquery follow scroll

I have a sort of sidebar on my website, which has to scroll down together with the user so that it is always in the view.
The code I'm using now is actually working fine however there is one problem. On smaller screens the sidebar scrolls before your at the sidebar thus making it impossible to see it all even if you scroll.
So what I want is the sidebar to scroll with the bottom instead of it being pushed down with the top so that when you reach the end of the sidebar it starts to scroll.
This is the code that I'm currently using.
var documentHeight = 0;
var topPadding = 10;
$(function() {
var offset = $("#mainright").offset();
documentHeight = $(document).height();
$(window).scroll(function() {
var sideBarHeight = $("#mainright").height();
if ($(window).scrollTop() > offset.top) {
var newPosition = ($(window).scrollTop() - offset.top) + topPadding;
var maxPosition = documentHeight - (sideBarHeight);
if (newPosition > maxPosition) {
newPosition = maxPosition;
}
$("#mainright").stop().animate({
marginTop: newPosition
});
} else {
$("#mainright").stop().animate({
marginTop: 0
});
};
});
});
I guess the "best practice" for accomplishing a task like this is to use dynamically changing css position from absolute to fixed and vice versa. A basic example could look like:
$(function(){
var $box = $('.box'),
offset = $box.offset(),
doc_h = $(document).height();
$(window).scroll(function(){
if($(window).scrollTop() > offset.top) {
if(!$box.hasClass('fix'))
$box.toggleClass('normal fix');
}
else{
if(!$box.hasClass('normal'))
$box.toggleClass('normal fix');
}
});
});​
Example in action: http://www.jsfiddle.net/YjC6y/14/
$(function() {
var top = 50;
$(window).scroll(function() {
$('#box').stop().animate({ top: $(window).scrollTop() + top}, 1000);
});
});
Try the example : http://jsbin.com/omiyi3
I think you can instead make the sidebar responsive by throwing your function into one of these:
if (responsive_viewport >= 768) {}
This makes it so that the function will only load if the viewport is bigger than or equal to 768px.

Categories

Resources