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');
}
});
});
Related
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);
}
});
I tried a lot of solutions but I cant make the divs stop following the scroll at the footer.
Here is my code to make the divs follow the scroll (colderecha and colizquierda are my divs that follow the scroll):
$(document).ready(function () {
var top = $('#colizquierda').offset().top - parseFloat($('#colizquierda').css('marginTop').replace(/auto/, 0));
$(window).scroll(function (event) {
var y = $(this).scrollTop();
//if y > top, it means that if we scroll down any more, parts of our element will be outside the viewport
//so we move the element down so that it remains in view.
if (y >= top) {
var difference = y - top;
$('#colizquierda').css("top",difference);
}
});
});
$(document).ready(function () {
var top = $('#colderecha').offset().top - parseFloat($('#colderecha').css('marginTop').replace(/auto/, 0));
$(window).scroll(function (event) {
var y = $(this).scrollTop();
//if y > top, it means that if we scroll down any more, parts of our element will be outside the viewport
//so we move the element down so that it remains in view.
if (y >= top) {
var difference = y - top;
$('#colderecha').css("top",difference);
}
});
});
What I have tried:
$(document).scroll(function() {
checkOffset();
});
function checkOffset() {
if ($('#colizquierda').offset().top + $('#colizquierda').height() >= $('#footer').offset().top - 10)
$('#colizquierda').css('position', 'absolute');
if ($(document).scrollTop() + window.innerHeight < $('#footer').offset().top)
$('#colizquierda').css('position', 'fixed');
if ($('#colderecha').offset().top + $('#colderecha').height() >= $('#footer').offset().top - 10)
$('#colderecha').css('position', 'absolute');
if($(document).scrollTop() + window.innerHeight < $('#footer').offset().top)
$('#colderecha').css('position', 'fixed');
}
I try to make sure that a div "filter" becomes fixed when scrolling and then stop when it comes down to "outside_footer_wrapper". use the following script but can not get it to work?
jsfiddle
$(function() {
var top = $('#filter').offset().top - parseFloat($('#filter').css('marginTop').replace(/auto/, 0));
var footTop = $('#outside_footer_wrapper').offset().top - parseFloat($('#outside_footer_wrapper').css('marginTop').replace(/auto/, 0));
var maxY = footTop - $('#filter').outerHeight();
$(window).scroll(function(evt) {
var y = $(this).scrollTop();
if (y > top) {
if (y < maxY) {
$('#filter').addClass('fixed').removeAttr('style');
} else {
$('#filter').removeClass('fixed').css({
position: 'absolute',
top: (maxY - top) + 'px'
});
}
} else {
$('#filter').removeClass('fixed');
}
});
});
If you want to stop the position:fixed after you reach the footer you can do something like this faking with the top:
$(function() {
var top = $('#filter').offset().top,
footTop = $('#outside_footer_wrapper').offset().top,
maxY = footTop - $('#filter').outerHeight();
$(window).scroll(function(evt) {
var y = $(this).scrollTop();
if (y > top) {
$('#filter').addClass('fixed').removeAttr('style');
if (y > maxY-20){
var min = y - maxY + 20;
$('#filter').css('top','-'+min+'px');
}
} else {
$('#filter').removeClass('fixed');
}
});
});
Also take in care with the CSS for the class fixed you need to make that with equal specificity of #filter I made this change:
#sidebar #filter.fixed /*Add #sidebar*/
Check This Demo Fiddle
if you know at which pixel number the filter have to be fixed and at which pixel number the footer starts you can try this function:
scrollTop
Is it something like this?
jsfiddle
// get box div position
var box = document.getElementById('box').offsetTop;
window.onscroll = function(){
// get current scroll position
var scroll_top = document.body.scrollTop || document.documentElement.scrollTop;
document.getElementById('scbox').innerText = scroll_top + ' ' + box;
// if current scroll position >= box div position then box position fixed
if(scroll_top >= box)
document.getElementById('box').style.position = 'fixed';
else
document.getElementById('box').style.position = 'relative';
}
try this:
#sidebar {
position: fixed;
}
jsfiddle here
I'm using the HTML5 attribute draggable = "true" on some of my divs on my webpage. I want it so that when you drag one of these items to the bottom of the page, it scrolls the page down and when you drag it to the top, it scrolls the page up.
I will eventually make a playlist on my sidebar, and since it will not always be on view depending on where you're looking on the page, the page needs to scroll when you're dragging.
My page is here and you can try dragging the pictures of the posts around. On Chrome, it automatically lets me scroll down when I drag to the bottom, but not up. On Firefox, it doesn't automatically let me scroll either direction. Any help?
Here's a simple jsfiddle to get you started. On Chrome you should be able to drag the Google icon down and have it scroll the page down, but not going up.
here is a code that will scroll-up or scroll-down your page while you are dragging something. Just placing your dragging object at top or bottom of the page. :)
var stop = true;
$(".draggable").on("drag", function (e) {
stop = true;
if (e.originalEvent.clientY < 150) {
stop = false;
scroll(-1)
}
if (e.originalEvent.clientY > ($(window).height() - 150)) {
stop = false;
scroll(1)
}
});
$(".draggable").on("dragend", function (e) {
stop = true;
});
var scroll = function (step) {
var scrollY = $(window).scrollTop();
$(window).scrollTop(scrollY + step);
if (!stop) {
setTimeout(function () { scroll(step) }, 20);
}
}
I have made a simple JavaScript drag and drop class. It can automatically scroll up or down the page while dragging.
See this jsfiddle. Also avaliable at my github page.
Dragging at a high speed is not recommended now. I need to work out that.
Code below is a part of the library.
var autoscroll = function (offset, poffset, parentNode) {
var xb = 0;
var yb = 0;
if (poffset.isBody == true) {
var scrollLeft = poffset.scrollLeft;
var scrollTop = poffset.scrollTop;
var scrollbarwidth = (document.documentElement.clientWidth - document.body.offsetWidth); //All
var scrollspeed = (offset.right + xb) - (poffset.right + scrollbarwidth);
if (scrollspeed > 0) {
this.scrollLeft(parentNode, scrollLeft + scrollspeed);
}
scrollspeed = offset.left - (xb);
if (scrollspeed < 0) {
this.scrollLeft(parentNode, scrollLeft + scrollspeed);
}
scrollspeed = (offset.bottom + yb) - (poffset.bottom);
if (scrollspeed > 0) {
this.scrollTop(parentNode, scrollTop + scrollspeed);
}
scrollspeed = offset.top - (yb);
if (scrollspeed < 0) {
this.scrollTop(parentNode, scrollTop + scrollspeed);
}
} else {
var scrollLeft = offset.scrollLeft;
var scrollTop = offset.scrollTop;
var scrollbarwidth = parentNode.offsetWidth - parentNode.clientWidth; //17
var scrollbarheight = parentNode.offsetHeight - parentNode.clientHeight; //17
var scrollspeed = (offset.right + xb) - (poffset.right - scrollbarwidth);
if (scrollspeed > 0) {
this.scrollLeft(parentNode, scrollLeft + scrollspeed);
}
scrollspeed = offset.left - (xb + poffset.left);
if (scrollspeed < 0) {
this.scrollLeft(parentNode, scrollLeft + scrollspeed);
}
scrollspeed = (offset.bottom + scrollbarheight + yb) - (poffset.bottom);
if (scrollspeed > 0) {
this.scrollTop(parentNode, scrollTop + scrollspeed);
}
scrollspeed = offset.top - (yb + poffset.top);
if (scrollspeed < 0) {
this.scrollTop(parentNode, scrollTop + scrollspeed);
}
}
};
Here is the javascript version of AngularPlayers answer, I added horizontal support. I noticed both the JQuery solution and Javascript solution have a bug on mobile safari that allows the page to infinitely grow when the bounce effect from overscrolling happens.
The purpose of VerticalMaxed and HorizontalMaxed is to check that the scroll bars are not maxed before scrolling again. This prevents the page from growing during overscroll bounce.
var stopX = true;
var stopY = true;
document.addEventListener('drag', function(e) {
if (event.target.classList.contains('draggable')) {
stopY = true;
// Handle Y
if (e.clientY < 150) {
stopY = false;
scroll(0,-1)
}
if ((e.clientY > ( document.documentElement.clientHeight - 150)) && !VerticalMaxed()) {
stopY = false;
scroll(0,1)
}
// Handle X
stopX = true;
if (e.clientX < 150) {
stopX = false;
scroll(-1,0)
}
if ((e.clientX > ( document.documentElement.clientWidth - 150)) && !HorizontalMaxed()) {
stopX = false;
scroll(1,0)
}
}
});
document.addEventListener('dragend', function(e) {
if (event.target.classList.contains('draggable')) {
stopY = true;
//stopY = true;
stopX = true;
}
});
// On drag scroll, prevents page from growing with mobile safari rubber-band effect
var VerticalMaxed = function(){ return (window.innerHeight + window.scrollY) >= document.body.offsetHeight}
var HorizontalMaxed = function(){ return (window.pageXOffset) > (document.body.scrollWidth - document.body.clientWidth);}
var scroll = function (stepX, stepY) {
var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
window.scrollTo((scrollX + stepX), (scrollY + stepY));
if (!stopY || !stopX) {
setTimeout(function () { scroll(stepX, stepY) }, 20);
}
}
I have a floating sidebar in my website www.rayshaft.com and I also have ajax pagination, so the sidebar is supposed to be floating until it reaches the footer of the page, but the problem is it works only with the 1st page, when the 2nd page is loaded via ajax the sidebar is not floating.
I was suggested to change my js code so that every time after ajax page load i need to call scroll function again or i need to recalculate maxY and footTop ech time scroll happens. I don't know any js programming so could you please help me. How can I modify this code to get what I want?
$(window).load(function(){
$(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 > top) {
if (y < maxY) {
$('#sidebar').addClass('fixed').removeAttr('style');
} else {
$('#sidebar').removeClass('fixed').css({
position: 'absolute',
top: (maxY - top) + 'px'
});
}
} else {
$('#sidebar').removeClass('fixed');
}
});
Make the function for the scrollbar a standalone function, and then call it when the ajax script finishes.
function ScrollBar()
{
$(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 > top) {
if (y < maxY) {
$('#sidebar').addClass('fixed').removeAttr('style');
} else {
$('#sidebar').removeClass('fixed').css({
position: 'absolute',
top: (maxY - top) + 'px'
});
}
} else {
$('#sidebar').removeClass('fixed');
}});
}
}
$(window).load(function(){
ScrollBar();
});
now as soon as the ajax pagination finishes, call this function: ScrollBar() to relocate the scrollbar.