I've found and adapted this method to have my div follow down the scroll bar, only after a certain point is reached:
$.fn.followFrom = function (pos, left_fixed, left_absolute) {
var $this = this,
$window = $(window);
$window.scroll(function (e) {
if ($window.scrollTop() < pos) {
$this.css({ // no move
position: 'absolute',
top: 400,
left: left_absolute
});
} else { // move
$this.css({
position: 'fixed',
top: 220,
left: left_fixed
});
}
});
};
Strangely (or not?), it works only when my div has content to its right.
But when it's the bottom element on the screen, then when scrolling and position is reached, hop the scroll bar jumps back to the top, which is a very frustrating user experience.
The context is a search page, where I have a map in my moving div on the left, and the search results on the right. So I want that when scrolling down the results, the map stays visible on the left.
So it works only when there are results AND the results height is bigger than the map's height. But as soon as the results' height gets shorter, then I get the jump.
Thanks
Related
I'm building a website with a sidebar that, once the user scrolls past a certain point it becomes fixed on the site. This code works fine.
The issue that I am coming into is that the sidebar is overlapping the footer when the user scrolls to the bottom of the page. I wrote code to detect when the bottom of the sidebar hits the same position as it's containing element - when that happens I am taking the position of the bottom of the containing element and subtract the height of the sidebar element and using that number to give the sidebar it's new "top" (while also changing the position to "absolute").
This is where I am running into the issue - once the sidebar is overtop of the footer as the user scrolls the code that is getting called alternates between the normal "fixed" position code and the "absolute" positioned code giving it this flickering effect.
For the life of me I can't figure out why the "fixed" code keeps getting called.
Here is the code:
( function( $ ) {
var sidebar_pos = $('#secondary')[0].getBoundingClientRect();
var pos_top = sidebar_pos.top + window.scrollY; //need this to get the pos of TOP in the browser - NOT the viewport
var main_pos = $('.main-content')[0].getBoundingClientRect();
var main_bottom = main_pos.bottom + window.scrollY;
var stop_pos;
var i = 0;
$(window).scroll(function(event){
var scroll = $(window).scrollTop();
var produce_pos = $('.produce')[0].getBoundingClientRect();
var pos_bottom = produce_pos.bottom + window.scrollY;
//console.log("scroll "+scroll);
//console.log("top " + pos_top);
console.log(main_bottom);
console.log('bottom ' + pos_bottom);
if( scroll >= pos_top){
if ( pos_bottom >= main_bottom ){
//if the sidebar would end up overlapping the footer
if(i == 0){
//only need to set this once, not on every scroll
stop_pos = main_bottom - $('#secondary').height() ;
}
$('#secondary').removeClass('hover').css({
position: 'absolute',
margin:0,
left: sidebar_pos.left,
top: stop_pos
});
i++;
} else {
$('#secondary').addClass('hover').css({
position: 'fixed',
left: sidebar_pos.left,
marginTop: '1.5em',
top: 20
});
setTimeout(() => {
$('*[data-widget="comet"]').addClass('active');
}, 5000);
setTimeout(() => {
$('*[data-widget="produce"]').addClass('active');
}, 7000);
}
} else if( scroll < pos_top && $('#secondary').hasClass('hover') ){ //if user scrolls up past original pos of sidebar, remove effects
$('#secondary').removeClass('hover').css({
position: 'relative',
left: 'auto',
top: 'auto'
});
i = 0;
}
});
}( jQuery ) );
I also have a codepen of the script in action.
https://codepen.io/antlaur00/pen/ExyrgYR
Any help is much appreciated! Thanks!
Well its pretty simple, just add Z-index property to your footer CSS, that way it will always overlap your sidebar .
You can refer to this article regarding the z-index property
https://www.w3schools.com/cssref/pr_pos_z-index.asp
Most webpages load so that you're at the top of the page by default. If you're halfway down a page, and click Refresh/Reload, most browsers will reload the page, but you'll still be wherever you were on that page.
If you have sticky navigation that relies on scroll position, this means that your navigation may not appear correctly until you scroll.
I have tried to get the value by using something like this in jQuery:
var h_offset = $('.h').position();
alert(h_offset.top);
However, this will report 0 since my .h div is positioned absolutely to the top of the browser, even if I'm scrolled halfway down the page.
Is there a way to get the distance between the top of the document and where the .h is as far as how far down the page you've scrolled?
You can use document.documentElement.scrollTop to check the position of the Y scroll axis of the page after page load.
You can use jQuery .offset() to get the offset top and left of an absolute positioned element after page load.
$(window).on('load', function() {
let scrollTop = document.documentElement.scrollTop;
console.log('scrollTop', scrollTop);
// Get the offset (left, top) of #abs element after page load
let { left, top } = $('#abs').offset();
console.log('#abs top', top);
if (scrollTop === 0) {
// We are at the top
} else {
// The page is scrolled down by scrollTop pixels
// Use scrollTop and left to calc new scroll value or set it to 0
// You can use this to scroll the page at the top after each load
setTimeout(() => {
window.scrollTo(0, 0);
}, 50);
}
});
$(window).on('load', function() {
let scrollTop = document.documentElement.scrollTop;
console.log('scrollTop', scrollTop);
let { left, top } = $('#abs').offset();
console.log('#abs top', top);
if (scrollTop === 0) {
// We are at the top
} else {
// The page is scrolled down by scrollTop pixels
// You can use this to scroll the page at the top after each load
setTimeout(() => {
window.scrollTo(0, 0);
}, 50);
}
});
#abs {
position: absolute;
left: 100px;
top: 2000px;
width: 20px;
height: 20px;
background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>Top of the page</h1>
<div style="margin-bottom: 2000px"></div>
<h1>Bottom of the page</h1>
<div id="abs"></div>
I want to display the popup on the top of element if there is no proper space on the top. Currently it hides inside the window as seen in the image below:
I can update the top position but I only want when there is no proper space otherwise it is ok.
Please let me know how to determine if the clicked position in near window edges.
JSFiddle Link :http://jsfiddle.net/g4g4negf/
Code I am using to get the position:
$(document).ready( function() {
$('.clickme').on('click', function(e) {
$('#popup').offset({ top: e.pageY, left: e.pageX}).fadeIn();
});
Check out this JSFiddle
To check if clicked position is near window edge, you have to get window's height ($(window).height()) and scroll position (window.pageYOffset). By adding these two values, you can find the scrolled position of the window. Then compare this sum with e.pageY+$("#popup").height() (this is the sum of the clicked position's height and the popup's height). If the latter is less than the former, it means the popup can be shown. If (e.pageY+$("#popup").height())>($(window).height()+window.pageYOffset) it means the popup will overflow the window's bottom border, then its top offset should be changed to e.pageY-$('#popup').height().
Here is the complete function:
$('.clickme').on('click', function(e) {
var h;
if((e.pageY+$('#popup').height())<($(window).height()+window.pageYOffset)) h=e.pageY;
else h=e.pageY-$('#popup').height();
$('#popup').offset({ top: h, left: e.pageX}).fadeIn();
});
Considering your popup height is 100px, you can try this...
$(document).ready( function() {
var h = window.innerHeight;
$('.clickme').on('click', function(e) {
alert(h + ", " + e.pageY);
if( h - e.pageY < 125) {
$('#popup').offset({ top: h-125, left: e.pageX}).fadeIn();
}
else {
$('#popup').offset({ top: e.pageY, left: e.pageX}).fadeIn();
}
});
});
What I want to do is have a fixed navigation bar that is 10px from the top of the window unless it is within the first 200px of the document, then I want it to be 200px from the top ...
So basically I want a navigation bar that is 200px from the top to start off with, but when the user scrolls down 190px the navigation bar scrolls, staying always 10px from the top of the window.
You first listen to the scroll event of the window, and then use the scroll value to know what state to apply to you element. Example with jQuery :
var fixed = false, limit = 50;
$(window).scroll(function()
{
if (window.scrollTop < 50 && fixed)
{
$("#header").css({ position: "relative" });
fixed = false;
}
else if (window.scrollTop > 50 && !fixed)
{
$("#header").css({ position: "fixed" });
fixed = true;
}
});
Also related to this post for code example
I need that when I scroll down or up with mouse wheel or sidebar my div change incrementally the Y position (for example 50px up or down ). I need this in Javascript/Jquery.
I Try this code, but only works for scrolling down(The Scrolling Down and Up Function is working well, only the animate part is working wrong):
UPDATE:
var sidebarScrollTop = 0;
$(document).ready(function() {
sidebarScrollTop = $("body").offset();
$(window).scroll(function ()
{
var docScrollTop = $('body,html').scrollTop();
if(docScrollTop > sidebarScrollTop.top)
{
$("#legend").stop().animate({ marginTop: "+=50px",}, 'slow', "easeOutCirc" );
}
else
{
$("#legend").stop().animate({ marginTop: "-=50px",}, 'slow', "easeOutCirc" );
}
});
});
$(window).resize(function()
{
sidebarScrollTop = $("#legend").offset().top;
});
$(document).resize(function()
{
sidebarScrollTop = $("#legend").offset().top;
});
Thanks
You can use
$(window).scroll(function() {
// Your scroll code here
});
to grab whenever the user is scrolling on the page.
Next you want to change the div's y-value.
If the div is positioned absolute, this is just changing its top-value.
$('my-div').top = original-top-value + $(window).pageYOffset;
I believe you need is to keep the div always showing even when user scrolls down. If that is the case then it can be done with only CSS:
div {
position: fixed;
z-index: 100;
top: 100px;
left: 100px;
}
The values of z-index, top and left are dummy values. Change em with your ones.
UPDATE:
Since CSS Solution won't work for you, here is a working example writter in JS: http://jsfiddle.net/qCtt5/