How to calculate remaining height even when overflow scroll stops. [JQUERY] - javascript

I created a custom scrollbar behavior of a div that goes down based on calculated; height of parent and current position scrollTop.
However, when the content reaches the end, the div stays in the middle and does not go beyond the top: 100% (actually it's 85 to be precise) How can I calculate that the div actually goes to the bottom?
$('.carousel-items').scroll(function() {
var currY = $(this).scrollTop();
console.log(currY);
var postHeight = $(this).height();
var scrollHeight = $('.carousel-item').height();
var scrollPercent = (currY / (scrollHeight - postHeight)) * 100;
scrollPercent = Math.abs(scrollPercent);
$('.test').css('top', scrollPercent +"%" );
});
I tried multiplying the sum by 1000 instead of 100, but the items in the content are dynamically added. I am now in a test environment (experimenting with 4 items) but when the project finishes the items in it could be like 20..
As you can see in the image, the scrollbar is reaches the end but the blue T div stays at the middle.
enter image description here

Related

Set div width based on scroll position

The code:
http://codepen.io/anon/pen/EjrpMM
So, i'm working on an interesting problem. I am working with a 2000px HTML document, that has a modal placed ontop of it.
The width of the div lightbox is 80%, and it's sitting positioned fixed.
The goal is, when scrolling down the page, to control the width of the div based on the scroll position. At the bottom of the page, it's only a third in size.
I've had trouble figuring out the proper equation or formula for this, and was seeking help.
Currently, I've been trying to look at the window.pageYOffset, to add 2.5% to the div while increasing, and minus 2.5% when scrolling back up, to bring it back to it's 80% width.
However, something isn't working right. I was seeing if the community had any ideas to help solve the problem.
I'm not using any frameworks for this.
Here's my javascript:
var lightBox = document.getElementById('lightBox'),
count = 80,
num = window.pageYOffset;
document.addEventListener('scroll', function(e) {
var offset = window.pageYOffset;
num >= offset ? count += 2.5 : count -= 2.5;
num = offset;
lightBox.style.width = count + '%';
});
View the code here, in this codepen
http://codepen.io/anon/pen/EjrpMM
Thank you!
You just have to change
+= 2.5 and -=2.5 to += 0.7 and -= 0.7
When I checked your code I did this and it worked.
Scroll event fired once on scroll independently on how much you've scrolled. E.g. if you've scrolled 1px scrollbar, or scrolled 100px using mousewheel scroll event will be fired once.
So if you need stable results you will need to calculate your div width depending on scroll position (window.pageYOffset).
Check this codepen fork. I've assumed that in the end of page div width should be 50%.
Core part is:
var lightBox = document.getElementById('lightBox');
var upperBound = 80;
var lowerBound = 50;
var tickValue = (upperBound - lowerBound) / window.innerHeight;
document.addEventListener('scroll', function(e) {
var offset = window.pageYOffset;
var count = upperBound - offset * tickValue;
lightBox.style.width = count + '%';
});
Important note: for crossbrowser way to get innerHeight you can check this answer
This is a simple equation. Let f : scroll |-> f(scroll) be the function that gives you the width of your div. You want f(0) = 0.8, f(2000)= 1/3.
Let's say you want the progression to be linear so f(scroll) = a*scroll + b, you can easily deduce that b = 0.8 and a = (1/3 - 0.8)/2000 = -0.000233. Now for any scroll value, you can find the width of your div.
Now you can change the values when you want, f(scroll) = (minWidth-maxWidth)/pageLength * scroll + maxWidth.

why the width of elements are different after page load and after that moment?

The situation is that I want to change the size of an element right after the page load. The problem is that the element did not change because the result returned by the function getSearchBarWidth was negative number. Something strange here is that console prints incorrect values of the width of the two element web_logo and menu; their width should be small, but in the console, the width of both elements are equal the parent element, which is a navigation bar. But later, I print out again the width of two element in console, the result was correct. Can someone explain this?
update: it seems because I don't specify the width of the navigation bar. So is there any other except specify the width of the parent element to get the correct width of its children right after page loads?
<script src="js/function.js" defer></script>
Content of file js
// calculate the width of window and relevant element
function getSearchBarWidth(){
var wWidth = $(window).width();
var offset = 20; // distance between the search bar and each of the two next elements
var offset_1 = 15; // padding of each sides of the navi bar
var searchBarWidth = wWidth - $("#navi_bar > .web_logo").width() - $("#navi_bar > .menu").width() - 2*offset - 2*offset_1;
return searchBarWidth;
}
// change the size of search bar
if($("#navi_bar > .search_bar").length > 0){
console.log("window: "+ $(window).width());
console.log("logo: "+ $("#navi_bar > .web_logo").width());
console.log("menu: "+ $("#navi_bar > .menu").width());
$("#navi_bar > .search_bar").css("width", getWindowWidth());
}
My problem is solved. Just call setTimeout and then the width of element would be correct.

Div to follow scrollbar proportionally on a page

I'm now struggling on a sticky element that should scroll proportionally on a page. From top to the footer despite the page's height. So it's actually stick to the top of the scrollbar in the beginning and then to the bottom at the end. Or it just follows the scroll wheel.
Is there any chance to do it with jQuery ?
Below is the starting code with usual "sticky" div.
$(window).scroll(function(){
$("#sticky")
.animate({"marginTop":($(window).scrollTop())+"px"}, "fast");});
https://jsfiddle.net/flakessp/cxr78xc8/
Do you mean something like this?
$(window).scroll(function() {
// calculate the percentage the user has scrolled down the page
var scrollPercent = 100 * $(window).scrollTop() / ($(document).height() - $(window).height());
// get the height of the sticky element
var stickyHeight = $('.sticky').height();
// calculate the margin top of the sticky element
var marginTop = (($(window).height() - stickyHeight) / 100) * scrollPercent;
// set margin top of sticky element
$('.sticky').css('marginTop', marginTop);
});
Fiddle
So, this one was a little tricky, but here it is:
JSFiddle example
Basically, we're using a couple things here:
Scroll direction detection with this section:
var lastScrollPos = 0,
...
lastScrollPos < $window.scrollTop()
Then, you forgot to factor in things like document and window height. scrollTop does exactly what it says and only gives you the number from the top of the viewport to the top of the document. So we add in the visible height as well with $(window).height().
Then it's just a matter of whether we factor in the height of the element too (hence the ternary operator adding 0 or $('#sticky').height() depending on our scroll direction detection from the earlier section.
Anyhow, here's the full JS:
var lastScrollPos = 0,
$window = $(window),
$document = $(document),
$sticky = $('#sticky');
$(window).scroll(function(){
$sticky
.animate({"top":((($window.scrollTop() + (lastScrollPos < $window.scrollTop() ? $window.height() - $sticky.height() : 0))/$document.height()) * 100)+"%"}, "fast");
});

get percentage scrolled of an element with jquery

I'm trying to get an div to animate 0% - 100% relative to the percentage scrolled of an element.
Now I've set up a few variables, but I'm having trouble trying to calculate the height of one by percentage.
We can set the starting width quite easily and detect the scroll easily enough too, as can we get the height of the element that'll trigger the animation, I just can't get it as a percentage.
If I can figure out how to return the percent of conheight scrolled then this should be easy.
$(window).scroll(function() {
// calculate the percentage the user has scrolled down the page
var scrollPercent = ($(window).scrollTop() / $(document).height()) * 100;
$('.bar-long').css('width', scrollPercent +"%" );
});
Here's a jsfiddle, http://jsfiddle.net/SnJXQ/
This is animating bar-long based on the percent scrolled of the body element.
Animates from 0% - 100% (well, it doesn't really, but I can't figure out why).
What I'd like to do is get scroll percent of the .post div, then animate bar-long relative to that.
ie. Scrolled 10% of .post, .bar-long is 10% width, scrolled 70% of .post, .bar-long is 70% width.
Demo
Your problem is the same as How to get horizontal scrolling percentage of an HTML element in JavaScript?, but vertically.
Then, to get the vertically scrolled percentage, use
/* JS */ var scrollPercentage = 100 * containeR.scrollTop / (containeR.scrollHeight-containeR.clientHeight);
/*jQuery*/ var scrollPercent = 100 * $(containeR).scrollTop() / ($(containeD).height() - $(containeR).height());
In your case, containeR = window; containeD = document:
var scrollPercent = 100 * $(window).scrollTop() / ($(document).height() - $(window).height());
Ok I see what you are trying to achieve....in fact I just did something very similar. Most solutions I found out there also were only for full page examples with window or document properties. Instead I needed this in a specific div which in my case was actually used to update the horizontal position of another div.
First, you are going to want the scroll event attached to your $('.post')
Next, the height of the $('.content') is going to equal your actual Scroll Height
Lastly, apply your percentage formula : (Y / (scrollHeight - postHeight)) * 100 = scrollPercent
So instead of using document or window attributes your code should be as follows:
$('.post').scroll(function() {
var currY = $(this).scrollTop();
var postHeight = $(this).height();
var scrollHeight = $('.content').height();
var scrollPercent = (currY / (scrollHeight - postHeight)) * 100;
});
You can find the fiddle here: JS Fiddle For Div Scroll Percentage
The current project where I have implemented this is located here: Vertical Scroll Drives Horizontal Position
I hope this solves your problem :)
Let's say you want to keep track of the scroll of some document found in some IFrame in your page.
object.addEventListener("scroll", documentEventListener, false);
Then your event listener should look like this:
function documentEventListener(){
var currentDocument = this;
var docsWindow = $(currentDocument.defaultView); // This is the window holding the document
var docsWindowHeight = docsWindow.height(); // The viewport of the wrapper window
var scrollTop = $(currentDocument).scrollTop(); // How much we scrolled already, in the viewport
var docHeight = $(currentDocument).height(); // This is the full document height.
var howMuchMoreWeCanScrollDown = docHeight - (docsWindowHeight + scrollTop);
var percentViewed = 100.0 * (1 - howMuchMoreWeCanScrollDown / docHeight);
console.log("More to scroll: "+howMuchMoreWeCanScrollDown+"pixels. Percent Viewed: "+percentViewed+"%");
}

jQuery fixed sidebar that moves with content if overflow

I have the following fiddle: http://jsfiddle.net/yFjtt/1/
The idea is that the user can scroll PAST the header to make the sidebar 'stick' in place while they scroll further down the page.
As they near the bottom of the page it should then work out how much space is left and how much space the sidebar needs and the add some negative margin to move the sidebar upwards whilst maintaining the fixed position.
Upto here it all works fine.
The next problem is making sure that the sidebar only moves up as far as it needs to and should remain about 10 pixels from the bottom. This way the sidebar will be fixed until it needs to move upward to reveal its content and then once it's all shown become stuck again about 10 pixels from the bottom.
Here is where I have tried to achieve this (see fiddle for full code):
if( $(window).scrollTop() > (documentHeight - sidebarHeight) ) {
if( offsetBottom < 10) {
}
else {
$('div.sidebar').stop(true,false);
$('div.sidebar').animate({'margin-top':offset}, 300);
}
} else {
$('div.sidebar').stop(true,true);
$('div.sidebar').css({'margin-top':'0'});
}
However the sidebar STILL moves too far up the page... Can anyone help? I'm sure it's just a simple mistake working out the offset from the bottom.
I think you had a good try, except I'm not sure what those animations are doing there. Basically you need 3 checks, first to see if the use is above the header, second to check if they're between the header and the bottom most limit for the sidebar, and lastly if they're below that point. Then simply swap and change classes and modify top value as necessary.
jsFiddle
var sidebarHeight = $('div.sidebar').height();
var documentHeight = $(document).height();
var headerHeight = $('div.header').height();
$(window).scroll(function() {
var margin = 10;
var sidebar_offset = documentHeight - sidebarHeight - (margin * 2); // double margin to account for top and bottom margins
if ($(window).scrollTop() > headerHeight && $(window).scrollTop() < sidebar_offset ) {
// below header, but above the sidebar offset limit
$('div.sidebar').addClass('fixed');
$('div.sidebar').css('top', '');
}
else if ( $(window).scrollTop() <= headerHeight ) {
// above header
$('div.sidebar').removeClass('fixed');
$('div.sidebar').css('top', '');
}
else {
// past the sidebar offset limit
$('div.sidebar').removeClass('fixed');
$('div.sidebar').css('top', documentHeight - sidebarHeight - margin);
}
});​

Categories

Resources