I use this snippet to make an element "stop" at a certain point when scrolling.
$.fn.followTo = function (pos) {
var $this = this,
$window = $(window);
$window.scroll(function (e) {
if ($window.scrollTop() > pos) {
$this.css({
position: 'absolute',
top: pos
});
} else {
$this.css({
position: 'fixed',
top: 0
});
}
});
};
$('#braille').followTo(865);
The problem is that if there's not enough space to scroll (in higher resolutions), it's not positioned correctly.
It's important that you watch these 2 videos to understand how it works.
1920x1080: https://www.youtube.com/watch?v=WjT8FKAKTxA
It's properly positioned.
2775x1514: https://www.youtube.com/watch?v=oqQXm8BsfYA
Here instead as you can see it's not in the right place because there's not enough space to scroll
Resolutions until about 1190px height are ok, with higher resolutions there's this problem.
How can I solve this..? Can I set a followTo starting from the bottom of the page? Or set it in percentage? Or say "if height is > than 1190 just put that there"....
Here is the live webpage. To see what I'm talking about just zoom out like 3 times the resolution of your browser and try to scroll the page. The braille image isn't positioned properly under the music staff and above the yellow paragraph.
The short answer is yes, you can set followTo relative to the bottom of the page using $(document).height() - pos. The basic principle is:
$(window).scrollTop() == $(document).height() - $(window).height()
To change the followTo to work relative to the bottom of the page:
if ($(document).height() - $window.height() - $window.scrollTop() < pos)
To use a percentage you could do the calculation:
var percentageDownPage = $window.scrollTop() / ($(document).height() - $(window).height()) * 100;
if (percentageDownPage > pos) { /* your code*/ }
Related
There are tonnes of tutorials / examples of making a header stick on scroll for fixed height headers. However, I am working on a one page website and the initial section is a full screen image. The user then scrolls down to reveal the header and other content areas.
So my question is, how can I change my code to take into account the viewport / screen size - rather than use a fixed header size?
My existing code is:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 65) {
$(".main").addClass("sticky");
} else {
$(".main").removeClass("sticky");
}
});
You could use the height of the window instead of a fixed value (since you're talking about a full screen image, I'm guessing its height is equal to the window height):
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= $(window).height()) {
$(".main").addClass("sticky");
} else {
$(".main").removeClass("sticky");
}
});
You could also get the height of the first section, if it's smaller than the window
I don't know if there's a better solution, but here's my solution :
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= $(window).height()*0.2) { //0.2 for 20% of the viewport height, you can change this value if you need to
$(".main").addClass("sticky");
} else {
$(".main").removeClass("sticky");
}
});
I just used $(window).height() to get the viewport height.
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");
});
I make the scroller with top to bottom and bottom to top simultaneously. I did most of them. From bottom to top is working perfect and for top to bottom only causing somehow problem is works only if i increase the height of the div container. I am not sure where i could change the values to make it workable.
Here is the fiddle
JS
var percentageToScroll = 89;
var height = $(document).innerHeight();
var scrollAmount = height * percentageToScroll / 100;
alert(scrollAmount);
var overheight = jQuery(document).height() - jQuery(window).height();
//alert(overheight);
jQuery("html, body").animate({
scrollTop: scrollAmount
}, 900);
I did with percentage to animate the scroll.
You can click the bottom button in fiddle to see that. I want to scroll only 89% but it scroll fully to the bottom.
Much Appreciated your Help !!!
The top of the viewport will be at 89% of the document.
If for example your document is 100px in height, the top 89px will be off-screen and the bottom 11px are displayed (for as far as possible). If however you're screen-size is larger than this 11px, it can't scroll down that much.
What you probably want is:
var scrollAmount = ($(document).innerHeight() - $(window).height()) * percentageToScroll / 100;
Please try this it may helps you
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()){
alert("at bottom!");
}
});
You can also adjust it according to your requirment by reducing its height
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() > $(document).height()-100){
alert("near bottom!");
}
});
I am trying to get an fly-in / fly- out effect happening
Scroll down - animate in
Scroll-up animate out
To get a similar effect to the nizo website
http://nizoapp.com/
I have used this code I found on Stackoverflow "Fade in element on scroll down using css"
to determine whether the element is on screen, in the viewport, and then animate it.
$(window).scroll(function () {
/* Check the location of each desired element */
$('.article').each(function (i) {
var bottom_of_object = $(this).position().top + $(this).outerHeight();
var bottom_of_window = $(window).scrollTop() + $(window).height();
/* If the object is completely visible in the window, fade it it */
if (bottom_of_window > bottom_of_object) {
$(this).animate({
'opacity': '1'
}, 500);
}
});
});
Which works quite well.
I have added it to this demo page, and modified it.
http://saigonhousefinder.com/potteryone/fadinonscroll.html
(probably not live for long)
I have used css transitions to get the effect I am looking for. FLy-in Fly-out etc etc
And then I found..... this function which does the same thing
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
return ((elemTop <= docViewBottom) && (elemTop >= docViewTop));
}
Anyway.......
I cant get the animations to work when scrolling down, fly-in.
But I cannot get the animations to go in reverse when they fly out on scroll up
I thought the easiest way would be to detect if you are scrolling down of up, so I found this method / function
(function () {
var previousScroll = 0;
$(window).scroll(function () {
var currentScroll = $(this).scrollTop();
if (currentScroll > previousScroll){
$("#div").fadeIn("slow");
}
else {
$("#div").fadeOut("slow");
}
previousScroll = currentScroll;
});
}());
Which works well, but I cannot get it working.
At this point I can detect when an element is visible on the screen then add an effect to it.
What I need it to detect when that same element is beginning to go off the screen and apply another effect to it.
Any help on how to get this working would be great
Have a nice day
That's a really neat demo and a great concept! I played around with some code and it seems that you are almost there. You need to detect when the top of the screen meets the top of the element, so only calculate the offset once when the page is loaded. I added a 20px threshold so it kicks in a bit early. Let me know if this helps, it can be tweaked depending on how and when you want to call it. Here is a simple js fiddle demo
http://jsfiddle.net/XhAhR/23/
(function () {
var previousScroll = 0;
var elemTop = $("#div").offset().top;
$("#div").fadeOut();
$(window).scroll(function () {
var currentScroll = $(this).scrollTop();
if (currentScroll > previousScroll){
if(elemTop -20 > currentScroll){
$("#div").fadeIn("slow");
}
}
else {
if(elemTop - 20 > currentScroll){
$("#div").fadeOut("slow");
}
}
previousScroll = currentScroll;
});
}());
I found the following script to make a menu have a smooth animation following the screen when scrolling.
However, it's pushing down the footer, resulting the page height expanding with no further content. How do I make it stop scrolling when it collides with the footer?
Here's the code:
$(function() {
var $sidebar = $("#indhold_right"),
$window = $(window),
offset = $sidebar.offset(),
topPadding = 0;
$window.scroll(function() {
if ($window.scrollTop() > offset.top) {
$sidebar.stop().animate({
marginTop: $window.scrollTop() - offset.top + topPadding
}, "fast");
} else {
$sidebar.stop().animate({
marginTop: 0
});
}
});
});
Let us take a step back and see why it is happening the way it is happening.
When you scroll $window.scrollTop() AND offset.top both change. However, the former will always be greater than the latter. So, every time you scroll, your if condition evaluates to true and you are calling the animate function on it. You don't have a stop.
How do we put a stop? By putting a stop check beyond which you don't animate. When the page loads get the $("#footer").offset().top which is the footer height when you start. So, the check is against $window.scrollTop() which should be lesser than the footer top.
Will that check work? Yes, but it will not be pleasant(unless you want it that way) because your side bar has height and the stop works only after your sidebar top has reached the footer height(stop). So, just add the sidebar height to your stop. This will not be 100% accurate, there will be padding, margins, and other stuff that are not accounted for in this stop, but it looks pretty good and I think, you can continue from there.
Before I give you the code answer, please take a look at http://sscce.org/ (as mentioned by #Zeta). Always follow this. I had some time and a good mood. I wouldn't have even looked at it otherwise.
Below is the code. Working example - http://jsfiddle.net/H3Dqr/
$(function() {
var $sidebar = $("#indhold_right"),
$window = $(window),
offset = $sidebar.offset(),
topPadding = 0,
stop = $("#footer").offset().top;
$window.scroll(function() {
if ($window.scrollTop() > offset.top) {
if ($window.scrollTop() + $sidebar.height() < stop) {
$sidebar.stop().animate({
marginTop: $window.scrollTop() - offset.top + topPadding
}, "fast");
}
} else {
$sidebar.stop().animate({
marginTop: 0
});
}
});
});