Keep postion Y when opening offcanvas menu - javascript

I have an offcanvas menu and a container with content. When I scroll down the website and open and close the menu I'm tryng to keep the scrolled position on exactly the position I was at. Right now when closing the menu it scrolls back to the top of the site.
That is caused by some css styling I gave to the container to prevent scrolling I guess.
When I console.log offsetY then it shows when closing the menu 0 as offset.
So what I'm I doing wrong?
So what I have is this:
mainHeader.on('click', '.nav-trigger', function(event){
// open primary navigation on mobile
event.preventDefault();
mainHeader.addClass('nav-open');
$('.push-content, .offcanvas').addClass('nav-open');
var offsetY = window.pageYOffset,
$win = $(window),
$body = $('.container-fluid') ; // the content container
// Block scrolling
$body.css({
'position': 'fixed',
'top': -offsetY + 'px'
});
$win.scrollTop(offsetY);
});
$('.mobile-trigger').on('click', function(){ // btn to close menu again
var offsetY = window.pageYOffset,
$win = $(window),
$body = $('.container-fluid') ;
$body.css({
'position': 'relative',
'top': -offsetY + 'px'
});
mainHeader.removeClass('nav-open');
$('.push-content, .offcanvas').removeClass('nav-open');
});
Any help greatly appreciated.

I find it easier to make a class, for instance .no-scroll, and make the overflow-y property hidden. This will keep the content from being scrolled either direction and when you close the menu you can just remove the class. Also, by doing this it should maintain your current scroll position.

Related

Fix and Unfix scroll menu past the height of the div

I have a menu that gets fixed when you scroll to a certain position. However I need it to return to it's regular position and become unfixed when it scrolls past the content it is supporting.
So I need to calculate the height of the content container div and once it get to the end, unfix the menu.
This is because if I keep scrolling to the bottom of the page my menu keeps staying fixed even when iv'e scrolled onto my footer.
So how can I change this so that the scroll is only fixed to the height of the div that the fixed menu is supporting #js-contracts.
$(function(){
function fixDiv() {
var $cache = $('#js-contracts');
var divHeight = $('#js-months').height();
if ($(window).scrollTop() > 1210 & $(window).scrollTop() < divHeight+1210)
$cache.css({
'position': 'fixed',
'top': '63px',
'width':'inherit',
'padding-top':'10px',
'padding-bottom':'10px',
'background-color':'white'
});
else
$cache.css({
'position': 'relative',
'top': 'auto',
'background-color':'none',
'padding-bottom':'10px',
});
}
$(window).scroll(fixDiv);
fixDiv();
});

Set div to fixed until it comes into contact with other element where it becomes absolute. Won't revert back to fixed when scrolling back up

I'm having some trouble adding a sticky on scroll "Add to Cart" area to a product page.
So far I'm able to make the selected element become position: fixed from a certain point while scrolling until it reaches a 'cutoff point' so to speak, where it becomes position: absolute.
I also have a rule written to remove the position styling when I scroll above the 'starting point' for position: fixed. All of these are written inside one function which fires on $(document).scroll(). I'll post my code below.
The rules I've written seem to be working fine except for one specific thing. When I scroll down, the element becomes fixed. When the fixed element reaches the 'cutoff point' it switches to position: absolute and stays there when I continue scrolling. This is what I want.
The problem is when I start scrolling back up past the 'cutoff point' the element's positioning doesn't switch back to position: fixed. It stays position: absolute until I reach the top of the page where the styling is removed. I can then scroll down again and it will start all over again, fixed > absolute > not reverting back to fixed on scroll up.
function checkOffset() {
var div1 = $(".ProductMain");
var div2 = $(".SideRelatedProducts");
var div3 = $("#cssmenu");
var div1_top = div1.offset().top;
var div2_top = div2.offset().top;
var div3_top = div3.offset().top;
var div1_bottom = div1_top + div1.height();
var div2_bottom = div2_top + div2.height();
var div3_bottom = div3_top + div3.height();
// This is what removes styling assigned from scrolling, when element gets back to top of page
if (div1_bottom >= div3_bottom && $(window).width() > 900) {
$('.ProductMain').css({
'position': 'absolute',
'top': 'auto',
'bottom': '55px'
});
console.log('ABSOLUTE');
}
// This is what removes styling assigned from scrolling, when element gets back to top of page
if ($(document).scrollTop() > $('.main').offset().top + 20 && $(document).scrollTop() + div1.height() < (div2_top + 75) && div1_bottom < div3_bottom && $(window).width() > 900) {
$('.ProductMain').css({
'position': 'fixed',
'top': '60px',
'bottom': 'auto'
}); // restore when you scroll up
console.log('FIXED');
}
// This is what removes styling assigned from scrolling, when element gets back to top of page
if($(document).scrollTop() < $('.main').offset().top && $(document).scrollTop() + window.innerHeight < div2_top || $(window).width() < 900) {
$('.ProductMain').removeAttr('style');
}
}
$(document).scroll(function() {
checkOffset();
});
Thanks for your help!
This seems to be answered already. Please try this answer here:
Using jQuery to keep scrolling object within visible window

Sticky sidebar from bottom during scrolling

I'm planning to recreate the Medium.com like sidebar. This is what I have now but it's far from over.
Open the JSFiddle below to understand better; I am looking to do the following:
When you scroll down, it suddenly sticks to the bottom. How do I make it stick gradually as you scroll?
Because it uses position: fixed, it moves towards the right side without respecting the layout. How do I fix this?
When you scroll up and there's less space, it overlaps with the header as shown in the screenshot. Again, most likely because position: fixed is used.
How do I fix this? I know there's sticky-kit that does the work but I can't use any plugin.
HTML:
<div class="container">
<div class="row">
<div class="col-xs-12">
Header and Menu is placed here.
<hr />
</div>
<div class="col-xs-8">
<p>This is the main body which the user would be scrolling infinitely as more data gets loaded on scroll.</p>
</div>
<div class="col-xs-4">
<div id="sidebar">
<p>
This is the sidebar which I want to stop when it reaches the bottom like the one shown in medium dot com
</p>
</div>
</div>
</div>
</div>
Javascript:
function scrollCheck() {
var $right = $('#sidebar'),
scrollTop = $(window).scrollTop(),
windowHeight = $(window).height(),
docHeight = $(document).height(),
rightHeight = $right.height(),
distanceToTop = rightHeight - windowHeight,
distanceToBottom = scrollTop + windowHeight - docHeight;
if (scrollTop > distanceToTop) {
$right.css({
'position': 'fixed',
'bottom': (scrollTop + windowHeight > docHeight ? distanceToBottom + 'px' : '0px')
});
}
else {
$right.css({
'position': 'relative',
'bottom': 'auto'
});
}
}
$(window).bind('scroll', scrollCheck);
JSFIDDLE
I'll answer what questions of yours I could. Here is the edited Fiddle first.
As for your questions:
The sudden sticking to the bottom is caused because the element isn't the full length of the page so sticking it to the bottom with a fixed position will cause it to jump there. Whereas with the change I made so it sticks to the top there won't have this jump, as the element is at the top of the screen when scrolling so it can be discreetly fixed there.
This was because the element didn't have a fixed width and setting position: fixed; means that the elements width is no longer set by the parent, but the view port. So it expands to fill all the width in the view port it can.
This was happening because the position: fixed; was never removed when scrolling back above the elements original position, the updated if statement in the Js now removes the class with position: fixed; when scrolling above its original location.
A more detailed look into what I changed.
I added a CSS class so .toggleClass could be used to make the function cleaner.
.docked-sidebar {
position: fixed;
top: 0;
}
I also changed the conditions for the if statement so that they worked. Using .offset().top; to get the distance between the sidebar and the top of the page, while removing most of the other variables as they weren't needed. Finally I created bool variable(isDocked) so that the same condition isn't triggered multiple times.
var $right = $('#sidebar'),
isDocked = false,
initOffsetTop = $right.offset().top;
function scrollCheck() {
var scrollTop = $(window).scrollTop(),
offsetTop = $right.offset().top;
if (!isDocked && ((offsetTop - scrollTop) < 0)) {
$right.toggleClass("docked-sidebar");
isDocked = true;
} else if (isDocked && scrollTop <= initOffsetTop) {
$right.toggleClass("docked-sidebar");
isDocked = false;
}
}
For sticking to the bottom and then to the top exactly like the example website I recommend checking this question.

Move div with window scroll not consistent

I need my sidebar to scroll up and down with the window but stop when the div is at its top or bottom. The code below works when the page is first loaded and scrolled down or when the page is scrolled up slowly, but when the page is scrolled to the very bottom of the sidebar div, the page has to reach the top (and then some) in order to trigger that margin change.
Is there some other trigger I should be looking for besides just on scroll? How can I adjust this code to properly adjust the div?
$(window).on("load scroll", function() {
var scrollYpos = $(document).scrollTop();
var sidebarinfo = $("#sidebar").offset().top + $("#sidebar").height();
var windowinfo = $(window).height() + $(window).scrollTop();
if ((windowinfo)<(sidebarinfo)){
$('#sidebar').css('margin-top', -scrollYpos);
}
});
The sidebar div is fixed position. If I use absolute position, the div scrolls fine, but it doesn't stop when the bottom of the div has been reached - it just continues to scroll with the window.
I've fixed the main part of the problem with this code.
$(window).on("load scroll", function() {
var sidebarinfo = $("#sidebar").scrollTop() + $("#sidebar").height();
var windowinfo = $(window).innerHeight() + $(window).scrollTop();
if ((windowinfo)<(sidebarinfo)){
$('#sidebar').css('top', -($(window).scrollTop()));
}
});
The only problem is on page load, the sidebar gets stuck in the wrong position until it is scrolled all the way up (and more).
I actually figured out that I needed to adjust a few things and add an else clause:
$(window).on("scroll", function() {
var scrollmargin = $(window).scrollTop() - $("#sidebar").outerHeight();
var sidebarinfo = $("#sidebar").scrollTop() + $("#sidebar").outerHeight();
var windowinfo = $(window).innerHeight() + $(window).scrollTop();
console.log($(window).scrollTop());
if ((windowinfo)<(sidebarinfo)){
$('#sidebar').css('top', (sidebarinfo + scrollmargin)*-1);
}
else {
var margintop = $(window).innerHeight() - $("#sidebar").outerHeight();
$('#sidebar').css('top', margintop);
}
});

stick div to screen if bottom of div and screen matches

Hello all I am working on a project where in a page I have to stick the div to screen (disable scrolling) when its bottom is at the bottom of screen. I have two divs in the page and both the divs are of variable height. I want to stick the div2 and scroll the div1.
<script>
var divheight
var scrolltop
var screenheight
if(divheight-scrolltop <= screenheight){
/* now stick the div wherever it is i can not
use fixed position as both the divs are floating and
fixing the position will make it to change the position*/ }
else { /*un stick the div*/ }
</script>
i dont know what to put in if and else please help me
Make a function which fire on scroll. The main aim of the function would be to see the difference between screen height and bottom of the div. Once the difference is less than or equal to zero modify the css position to fixed. This will help you
(function ($) {
$('.DIV1').scroll(function () {
var $this = $(this),
win_ht = $(window).height(),
div_ht = $this.height(),
div_bot = $this.offset().top + div_ht;
if (win_ht - div_bot <= 0) {
$this.css({
'position': 'fixed',
'bottom': '0'
})
}
});
})(jQuery);

Categories

Resources