Javascript: scroll from one div to the other when scrolling? - javascript

I want to be able, when scrolling down, to go directly to the next div, and when scrolling up, to go directly to the previous div.
Here are my files with an example with two divs:
$(document).ready(function() {
var lastScrollTop = 0;
function findPos(obj) {
var curtop = 0;
if (obj.offsetParent) {
do {
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return [curtop];
}
}
$(window).scroll(function(event) {
var st = $(this).scrollTop();
if (st > lastScrollTop) {
$('html, body').animate({
scrollTop: $("#space_od").offset().top
}, 500);
} else {
$('html, body').animate({
scrollTop: $("#black_hole").offset().top
}, 500);
}
lastScrollTop = st;
});
});
body {
padding: 0;
margin: 0;
}
#black_hole {
background-image: url("black_hole.jpg");
background-position: center;
display: block;
height: 100vh;
width: 100%;
}
#space_od {
background-image: url("2001.png");
background-position: center;
display: block;
height: 100vh;
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="black_hole">
</div>
<div id="space_od">
</div>
It seems to work fine when scrolling down the first time, but not when scrolling up, it seems to move a few pixels and then stop. Any ideas?

scrollTo is a class to add to the divs you need to scroll to:
<div id="black_hole" class="scrollTo">
</div>
<div id="space_od" class="scrollTo">
</div>
Js
var scrolling = false;
var currentPos = 0;
function scrollUp(){
if(!scrolling && currentPos > 0 ){
scrolling=true;
currentPos --;
var scrollToElement = $('.scrollTo')[currentPos];
$('html, body').animate({
scrollTop: $(scrollToElement).offset().top
}, 500, function(){
scrolling = false;
});
}
}
function scrollDown(){
if(!scrolling && currentPos < $('.scrollTo').length-1 ){
scrolling=true;
currentPos ++;
var scrollToElement = $('.scrollTo')[currentPos];
$('html, body').animate({
scrollTop: $(scrollToElement).offset().top
}, 500,function(){
scrolling = false;
});
}
}
$(document).ready(function() {
// Get the current position on load
for( var i = 0; i < $('.scrollTo').length; i++){
var elm = $('.scrollTo')[i];
if( $(document).scrollTop() >= $(elm).offset().top ){
currentPos = i;
}
}
$(document).bind('DOMMouseScroll', function(e){
if(e.originalEvent.detail > 0) {
scrollDown();
}else {
scrollUp();
}
return false;
});
$(document).bind('mousewheel', function(e){
if(e.originalEvent.wheelDelta < 0) {
scrollDown();
}else {
scrollUp();
}
return false;
});
});

Related

CSS/JavaScript - Scroll snap when user starts scrolling

I recently found this website that uses scroll snapping. I looked into it and found that CSS supports this. However, it looks like snapping happens after the user stops scrolling. The same applies with the answer to this question.
The next thing I tried was using window.scrollTo and react-scroll, but both of these weren't as smooth as the website I've linked as an example since the user could still "fight" the scrolling by scrolling in the other direction.
I want it to scroll snap when the user starts scrolling. How can I do this with CSS or JavaScript?
The developer you were looking at is using this js script if you ant to emulate it exactly https://alvarotrigo.com/fullPage/
If jQuery is an option, that would be the easiest solution with the best browser compatibility. You can use the "wheel" event listener to detect the direction of the scroll, and then use jQuery animate to scroll the window to the appropriate element. I've provided an example based on this GitHub repo: https://github.com/epranka/sections-slider.
(function($) {
var selector = ".section";
var direction;
var $slide;
var offsetTop;
var $slides = $(selector);
var currentSlide = 0;
var isAnimating = false;
var stopAnimation = function() {
setTimeout(function() {
isAnimating = false;
}, 300);
};
var bottomIsReached = function($elem) {
var rect = $elem[0].getBoundingClientRect();
return rect.bottom <= $(window).height();
};
var topIsReached = function($elem) {
var rect = $elem[0].getBoundingClientRect();
return rect.top >= 0;
};
document.addEventListener(
"wheel",
function(event) {
var $currentSlide = $($slides[currentSlide]);
if (isAnimating) {
event.preventDefault();
return;
}
direction = -event.deltaY;
if (direction < 0) {
// next
if (currentSlide + 1 >= $slides.length) {
return;
}
if (!bottomIsReached($currentSlide)) {
return;
}
event.preventDefault();
currentSlide++;
$slide = $($slides[currentSlide]);
offsetTop = $slide.offset().top;
isAnimating = true;
$("html, body").animate({
scrollTop: offsetTop
},
1000,
stopAnimation
);
} else {
// back
if (currentSlide - 1 < 0) {
return;
}
if (!topIsReached($currentSlide)) {
return;
}
event.preventDefault();
currentSlide--;
$slide = $($slides[currentSlide]);
offsetTop = $slide.offset().top;
isAnimating = true;
$("html, body").animate({
scrollTop: offsetTop
},
1000,
stopAnimation
);
}
}, {
passive: false
}
);
})(jQuery);
.section {
position: relative;
display: flex;
height: 100vh;
}
#section1 {
background: blue;
}
#section2 {
background: #ff8c42;
}
#section3 {
background: #6699cc;
}
#section4 {
background: #00b9ae;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="section1" class="section"></div>
<div id="section2" class="section"></div>
<div id="section3" class="section"></div>
<div id="section4" class="section"></div>

Get scrollTop to run more than once

How is it possible to get the smooth scroll working more than once (with JQuery:s scrollTop)?
var projectContainer = document.getElementsByClassName('projectContainer')[0];
var position = $(window).scrollTop();
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll > position) {
$([document.documentElement, document.body]).animate({
scrollTop: $(".projectContainer").offset().top
}, 2000);
projectContainer.style.background = "orange";
$(window).bind("mousewheel", function() {
$("html, body").stop();
});
} else {
projectContainer.style.background = "white";
}
position = scroll;
});
.top {
height: 1000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="top">Scroll</div>
<div class="projectContainer">hello</div>
I've tried this but it only works for the first time after running the script.
Thanks in advance!

Applying a third condition to function

I have the following function which appliess css to #screen-nav when the user scrolls up and different css when user scrolls down
jQuery(document).ready(function($){
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('nav').outerHeight(true);
$(window).scroll(function(event) { didScroll = true; });
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 0);
function hasScrolled() {
if($( window ).width() > 768) {
var st = $(this).scrollTop();
if (Math.abs(lastScrollTop - st) <= delta)
return;
if (st > lastScrollTop) {
// Scroll Down
$('#screen-nav').removeClass('nav-down').addClass('nav-up');
} else {
$('#screen-nav').removeClass('nav-up').addClass('nav-down');
}
}
lastScrollTop = st;
}
});
css
#screen-nav {
position: fixed;
top: 0; left: 0; right: 0;
}
#screen-nav.nav-up { top: -100px; }
#screen-nav.nav-down { top: 0; }
I want to add a third class. I want #screen-nav { top: 50px; } when the user is 300px from the top. (so I figure apply a third class .nav-top when the user is in that position) But not sure how to integrate it into my code.
Basically, I want the nav (navigation) to appear lower on the page when the user is at the top, and when it comes down when the user scrolls up, I want it to be right at the top.
add condition of javascript
if(st == 300){ $("#screen-nav").css({ top: '50px' }); }
<script type="text/javascript">
jQuery(document).ready(function($){
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('nav').outerHeight(true);
$(window).scroll(function(event) { didScroll = true; });
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 0);
function hasScrolled() {
if($( window ).width() > 768) {
var st = $(this).scrollTop();
if (Math.abs(lastScrollTop - st) <= delta)
return;
if(st == 300)
{
$("#screen-nav").css({ top: '50px' });
}
else if (st > lastScrollTop) {
// Scroll Down
$('#screen-nav').removeClass('nav-down').addClass('nav-up');
}
else {
$('#screen-nav').removeClass('nav-up').addClass('nav-down');
}
}
lastScrollTop = st;
}
});
</script>

ScroolToTop show and hide based on user's scroll

How can show and hide a dive of scrolltotop.
Condition:
1. when user scrool down to 80 px it will be shown
2.if user clicks on it it it will take user to the top.
3. if a user stay 2 or more seconds in a certain position(it may maby 200px or more or less), the scroolbar also hidden. If he scroll up or down, the scroolbar visible then.
$(document).ready(function () {
$("#scrollup").hide('slow')
$(window).scroll(function (e) {
e.preventDefault();
if ($(window).scrollTop() > 80) {
$("#scrollup").show('slow');
}
if ($(window).scrollTop() < 80) {
$("#scrollup").hide('slow');
}
});
$(".scrollup").click(function () {
$("html, body").animate({ scrollTop: 0 }, 500);
return false;
});
});
i have done 1 and 2 condition , but how can i implement no 3?
Add setInterval(function(){ $("#scrollup").hide('slow'); }, 2000); and clear it on scroll
var idleInterval=null;
$(document).ready(function () {
$("#scrollup").hide('slow');
$(window).scroll(function (e) {
if(idleInterval != null)
clearTimeout(idleInterval);
idleInterval = setInterval(function(){ $("#scrollup").hide('slow'); }, 2000);
idleTime = 0;
e.preventDefault();
if ($(window).scrollTop() > 80) {
$("#scrollup").show('slow');
}
if ($(window).scrollTop() < 80) {
$("#scrollup").hide('slow');
}
});
$(".scrollup").click(function () {
$("html, body").animate({ scrollTop: 0 }, 500);
return false;
});
});
Demo:-
var idleInterval=null;
$(document).ready(function () {
$("#scrollup").hide('slow');
$(window).scroll(function (e) {
if(idleInterval != null)
clearTimeout(idleInterval);
idleInterval = setInterval(function(){ $("#scrollup").hide('slow'); }, 2000);
idleTime = 0;
e.preventDefault();
if ($(window).scrollTop() > 80) {
$("#scrollup").show('slow');
}
if ($(window).scrollTop() < 80) {
$("#scrollup").hide('slow');
}
});
$(".scrollup").click(function () {
$("html, body").animate({ scrollTop: 0 }, 500);
return false;
});
});
#pagewrap{
height:1000px;
}
#scrollup {
position: fixed;
color: white;
padding: 10px 30px;
background: red;
bottom: 30px;
right: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="pagewrap">
<h1>Demo</h1>
<h2>Animated Scroll to Top</h2>
<div id="scrollup">
scroll to top
</div>
</div>

jQuery autoScroll to the nearest section

If the user is place in the top half of current section it automatically scroll top of that section.
Then if the user is in the bottom half of the current section it automatically scroll to the top next section.
function autoScroll(aid){
var aTag = $("#"+ aid);
body.animate({scrollTop: aTag.offset().top},1500);
}
$(window).scroll(function() {
var windowScroll = $(window).scrollTop();
if(windowScroll < ($("#Section2").offset().top/2) && !(windowScroll > ($("#Section2").offset().top/2))){
section_id = 'Section1';
}
$(document).off('scroll');
console.log(section_id);
autoScroll(section_id);
});
http://jsfiddle.net/x6xzh69v/2/
I created a working example in CODEPEN.
$(document).ready(function() {
var origHeight = [];
var curScroll = 0;
var cumSumHeight = 0;
var animHeight = 0;
var i = 0;
var timeoutVar;
$(".section").each(function(index) {
origHeight.push($(this).height());
});
$(window).scroll(function() {
curScroll = $("body").scrollTop();
cumSumHeight = 0;
while ((cumSumHeight + origHeight[i]) < curScroll) {
cumSumHeight += origHeight[i];
i++;
}
if (i == 0) {
if (curScroll < (origHeight[i] / 2)) {
animHeight = 0;
} else {
animHeight = origHeight[i];
}
} else {
if ((curScroll - cumSumHeight) < (origHeight[i] / 2)) {
animHeight = cumSumHeight;
} else {
animHeight = origHeight[i] + cumSumHeight;
}
}
clearTimeout(timeoutVar);
timeoutVar = setTimeout(function() {
$("body").stop(true,true).animate({
scrollTop: animHeight
}, 200);
}, 300);
});
});
.section {
width: 100%;
position: relative;
height: 300px;
}
#Section1 {
background: red;
}
#Section2 {
background: blue;
}
#Section3 {
background: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section id="Section1" class="section"></section>
<section id="Section2" class="section"></section>
<section id="Section3" class="section"></section>

Categories

Resources