I am trying to perform a function/alert the user when they have scrolled down to a specific div, and then whey they have scrolled to the bottom of the page. I am able to alert when the user has scrolled to the bottom and back to the top, but not sure how to specify when the user scrolls below the fold(to the middle section). I have the following so far:
HTML
<div class="container top">TOP</div>
<div class="container middle">Middle</div>
<div class="container bottom">Bottom</div>
jQuery
$(function () {
var $win = $(window);
$win.scroll(function () {
if ($win.scrollTop() == 0) {
alert("USER SCROLLED TO TOP");
} else if ($win.height() + $win.scrollTop() == $(document).height()) {
alert("USER SCROLLED TO BOTTOM");
}
});
});
JSFIDDLE: LINK
https://jsfiddle.net/xsLx9ojs/1/
I add ids to the html divs:
<div id="top" class="container top">TOP</div>
<div id="bottom" class="container bottom">BOTTOM</div>
Then I add a condition to detect when bottom div appears in user's screen when he scrolls:
$(function () {
var $win = $(window);
$win.scroll(function () {
if ($win.scrollTop() == 0) {
console.log("USER SCROLLED TO TOP");
} else if ($win.height() + $win.scrollTop() >= $('#top').height() - 50
&& $win.height() + $win.scrollTop() <= $('#top').height() + 50) {
console.log("TRANSITION BETWEEN THE TWO DIVS");
} else if ($win.height() + $win.scrollTop() == $(document).height()) {
console.log("USER SCROLLED TO BOTTOM");
}
});
});
Scroll detection is not so precise cause of the little "jumps" that the mousewheel does. So I added a 100px tolerance. If I were you I would improve this stuff with a boolean that detects if the alert for bottom div has already been given or not so the function doesn't trigger at every scroll like this:
[...]
if ($win.scrollTop() == 0) {
//top reached
} else if ($win.height() + $win.scrollTop() >= $('#top').height()) {
//alert! bottom div appeared while scrolling bottom!
//deal with this with a boolean
} else if ($win.scrollTop() <= $('#top').height()) {
//alert! bottom div disappeared while scrolling top!
//deal with this with a boolean
} else if ($win.height() + $win.scrollTop() == $(document).height()) {
//bottom reached
}
[...]
Part of the issue is that the value of $(document).height() may never be obtained via scrolling, as elements within the page can affect the actual document height versus what the user is able to scroll through.
You could find the position of the bottom container like so
$('.bottom').position();
But that would only give you the element's position within its parent. You would then need to calculate the offset relative to each parent and grandparent, where applicable.
Likewise, you could look into the getBoundingClientRect function:
$('.bottom')[0].getBoundingClientRect();
Take a look at the library Waypoints to see a "ready-made" version.
Update 1:
For your JSFiddle sample, keep in mind that Waypoints needs to have an element hit the top of the window to trigger (this is by default - you can adjust this behavior with an offset).
See my JSFiddle here where I've made each div larger to allow the window to scroll passed, based on your JSFiddle.
Related
I have a part of code that looks if a user is scrolling up or down, and inside that check if the user is at the top of the page.
To see my position I log that position in my console but for some reason when I scroll up using my scroll wheel fast, it shows a number like 75, 98, 66 etc. Only when I scroll again (while it's already at the top) it goes to 0. Why?
$(window).bind('mousewheel', function(event) {
if (event.originalEvent.wheelDelta >= 0) {
var height = $(window).scrollTop();
console.log(height);
if(height > 20) {
$('.nav-link').css('color', '#2f323a');
}else{
$('.nav-link').css('color', '#ffffff');
}
}
});
I want to change the text color of my menu to white when a user is at the top but now if I scroll up fast using my mouse scroll it does not work right away.
Wouldn't you want to detect any kind of scroll? Not just mouse wheel.
$(document).ready(function() {
$(window).scroll(function() {
if ($(window).scrollTop() >= 20) {
$('.nav-link').css('color', '#2f323a');
} else {
$('.nav-link').css('color', '#ffffff');
}
});
});
I want to have my content fade in on scrolling, but it reacts to late. How can I change it, to have my content fade in earlier?
I am very new to javascript and couldn't get it worked yet.
$(window).on("load",function() {
$(window).scroll(function() {
var windowBottom = $(this).scrollTop() + $(this).innerHeight();
$(".fade").each(function() {
/* Check the location of each desired element */
var objectBottom = $(this).offset().top + $(this).outerHeight();
/* If the element is completely within bounds of the window, fade it in */
if (objectBottom < windowBottom) { //object comes into view (scrolling down)
if ($(this).css("opacity")==0) {$(this).fadeTo(500,1);}
} else { //object goes out of view (scrolling up)
if ($(this).css("opacity")==1) {$(this).fadeTo(500,0);}
}
});
}).scroll(); //invoke scroll-handler on page-load
});
Right now the content space is blank until I scroll to the bottom. I need to have my content fade in when it is on like half of the page or earlier. Maybe changeable to any height with percent or pixel?
The shared portion of code fades element in once they are completely in the viewport (= when bottom of the elements is in the window).
How about fading elements in as soon as their tops get in the viewport?
Fade out logic should remain as is: elements should be faded out once their bottom get out of the viewport.
Adapted code:
$(window).on("load",function() {
$(window).scroll(function() {
var windowBottom = $(this).scrollTop() + $(this).innerHeight();
$(".fade").each(function() {
/* Check the location of each desired element */
var objectTop = $(this).offset().top
, objectBottom = $(this).offset().top + $(this).outerHeight();
/* If the element's top gets within bounds of the window, fade it in */
if (objectTop < windowBottom) { //object comes into view (scrolling down)
if ($(this).css("opacity")==0) {$(this).fadeTo(500,1);}
} else if (objectBottom >= windowBottom){ //object goes out of view (scrolling up)
if ($(this).css("opacity")==1) {$(this).fadeTo(500,0);}
}
});
}).scroll(); //invoke scroll-handler on page-load
});
This code works well, but when I scroll up and down after 4-5 times it crashes and all the elements disappear. Why does this happen and how do I fix it?
$(window).on("load",function() {
$(window).scroll(function() {
var winheight = $(window).innerHeight();
$(".fade").each(function() {
/* Check the location of each desired element */
var objectBottom = $(this).offset().top + $(this).outerHeight();
var windowBottom = $(window).scrollTop() + $(window).innerHeight();
/* If the element is completely within bounds of the window, fade it in */
if ( windowBottom > (objectBottom - (winheight*0.65))) { //object comes into view (scrolling down)
if ($(this).css("opacity")==0) {$(this).fadeTo(500,1);}
} else { //object goes out of view (scrolling up)
if ($(this).css("opacity")==1) {$(this).fadeTo(500,0);}
}
});
}); $(window).scroll(); //invoke scroll-handler on page-load
});
Ok, I supposed that your html is something like this: https://jsfiddle.net/szdwwdac/
Sometimes, if you are scrolling fast up and down, when the element is fading out, your if doesn't work well.
if ( windowBottom >= (objectBottom - (winheight*0.65))) {
if ($(this).css("opacity")==0) {$(this).fadeTo(300,1);}
} else { //object goes out of view (scrolling up)
if ($(this).css("opacity")==1) {$(this).fadeTo(300,0);}
}
It's because of the 500ms of animation.
One of the solutions can be the eneble/disable for 500ms of the scroll page.
You can check this solution: How to disable scrolling temporarily?
EDIT
Another solution can be: add a class "fading" when you are inside your if. Then, in the if, eval if the element hasClass "fading". If not, you can go inside and make the animation.
I've been working on a scroll to top function for my website, and that part of it works fine. My problem is however that I have a fixed div that is overlapping my footer when it hits the bottom of the page.
Here is the function that I have working.
$(document).scroll(function (e) {
if (document.body.scrollTop >= 800) {
$('#beamUp').show(1000);
} else {
$('#beamUp').hide(1000);
return false;
}
});
Is there somehow I could detect when I hit that part of the page and stop the div from moving past that.Help is much appreciated!
jsFiddle: http://jsfiddle.net/zazvorniki/RTDpw/
Just get the height of the page, minus the height of the div in question, as well as the footer... make sure the top is never greater than that value... you'll also need an onresize event handler re-evaluate that value.
looking at your jsfiddle... here are my edits
In your scroll listener, I am checking for the position of the page, and adjusting the bottom position of the floater appropriately. I also set the initial display:none, so you don't need to call .hide() in your initial script. In addition, resizing the window has the effect of scrolling for your use, so I changed the listener for both events.
$(document).on('scroll resize', function (e) {
var viewHeight = $(window).height();
var viewTop = $(window).scrollTop();
var footerTop = $("footer").offset().top;
var baseline = (viewHeight + viewTop) - footerTop;
var bu = $("#beamUp").css({bottom: (baseline < 0 ? 0 : baseline) + 'px'});
if (viewTop >= 50) {
bu.show(1000);
} else {
bu.hide(1000);
}
});
I'm trying to have my content fade in when reaching a certain proximity to to respective ends of the page. The fade works fine when the trigger is set to the very top and bottom but when I set a distance (200px) the fade no longer works and the content simply appears.
$(window).scroll(function(){
if($(window).scrollTop()<=200){
$('#about .content').stop(true,true).fadeIn("5s");
}
else {
$('#about .content').stop(true,true).fadeOut("10s");
}
if ($(window).scrollTop() + $(window).height() >= $(document).height() - 200) {
$('#work .content').stop(true,true).fadeIn("5s");
} else {
$('#work .content').stop(true,true).fadeOut("5s");
}
});
What is happening is that you have two functions working against each other:
The first function has an "if-else" statement and the second function as well.
That means that each function does something EVERYTIME you scroll.
There are multiple ways of solving this.
The way I would solve it is using a variable and updating the constraints.
Let's say we have a variable onScreen that has value 1 if the paragraph is on the screen and value 0 if it isn't:
For example:
<div style="height: 800px">Example of scroll with fadeIn, fadeOut.
<p style="margin-top:300px;">These paragraphs will go away when you have scrolled
more than 10 pixels from the top. They will appear again when you have scrolled
to a proximity of 50 pixels from the bottom. They will also appear if you go
within a proximity of 10 pixels of the top again.</p>
</div>
Now for the jQuery code:
var $onScreen = 1;
$(window).scroll(function(){
if($(window).scrollTop() < 10){
if ($onScreen == 0)
{
$("p:first").stop(true,true).fadeIn("slow", "linear");
$onScreen = 1;
}
}
if($(window).scrollTop() <= 20 && $(window).scrollTop() >= 10){
if ($onScreen == 1)
{
$("p:first").stop(true,true).fadeOut("slow", "linear");
$onScreen = 0;
}
}
if ($(window).scrollTop() + $(window).height() >= $(document).height() - 50) {
if ($onScreen == 0)
{
$("p:first").stop(true,true).fadeIn("slow", "linear");
$onScreen = 1;
}
}
});
Now this is not the most concise way of doing it and I didn't mean to do so: by making the code a bit more extensive I hope you can follow why it works now and didn't work before (such that you actually learn from it).
I prepared a live example for you on Fiddle: http://jsfiddle.net/ycCAb/4/
I hope this answers your question. Good luck!