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!
Related
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>
I don't know if I'm doing it right but I want to scroll to the next div when the user scroll down and scroll to the previous div in the page when the user scroll up.
First of all I do this to test the scroll event and the animation of scrolling :
$(document).ready(function() {
$(window).scroll(function(){
$("html, body").animate({
scrollTop: 1000
}, 1000);
});
});
That's just a test but it work well.
Now, I want to differentiate the scroll down and the scroll up event to scroll to the next or the previous div so I search and I found some solutions like this :
$(document).ready(function() {
var lastPosition = $(window).scrollTop();
$(window).scroll(function(){
var newPosition = $(window).scrollTop();
if(lastPosition - newPosition > 0){
$("html, body").animate({
scrollTop: 1000
}, 1000);
}
else {
$("html, body").animate({
scrollTop: 0
}, 1000);
}
});
});
But it doesn't work...
I think the method to get the scroll down or the scroll up doesn't work in my case.
Do you have any solution to do this or maybe an alternative ?
Thank you.
In your case, the height of the body or your container should be set to the window height and the overflow of that should be set to hidden, because you want to scroll to the target Div by javascript.
by setting the overflow: hidden on the body or your container, you prevent
the window from scrolling on the page.
body {
background: #eee;
height: 100%;
overflow: hidden;
}
The next step is detecting the scrolling direction (Up/Down). You can
check it by the deltaY property of the scroll event.
Finally, get the next or previous Div and scroll to it.
The complete example is here
$(window).on('mousewheel DOMMouseScroll', function(event) {
var deltaY = event.originalEvent.deltaY || event.deltaY;
if (deltaY > 0) {
// Scrolled to Down: Next Div
} else if (deltaY < 0) {
// Scrolled to Up: Previous Div
}
});
You can see the completed code here:
<html>
<head>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" type="text/javascript"></script>
<style type="text/css">
body {
background: #eee;
height: 100%;
overflow: hidden;
}
.section {
height: 600px;
}
.section.active {
background: #ccc;
}
</style>
</head>
<body>
<div class="active section">Section 1</div>
<div class="section">Section 2</div>
<div class="section">Section 3</div>
<script type="text/javascript">
$(window).on('mousewheel DOMMouseScroll',function(event) {
var deltaY = event.originalEvent.deltaY || event.deltaY,
$activeSection = $('.section.active'),
$container = $('body'),
containerOffset = $container[0].offsetTop,
$targetSection = null,
mustBeScroll = false;
if(deltaY > 0) { // Scrolled to Down: Next Div
if($activeSection.next('.section').length > 0) {
$targetSection = $activeSection.next('.section');
mustBeScroll = true;
}
} else if (deltaY < 0) { // Scrolled to Up: Previous Div
if ($activeSection.prev('.section').length > 0) {
$targetSection = $activeSection.prev('.section');
mustBeScroll = true;
}
}
if(mustBeScroll == true) {
$container.stop(false, true).animate({ scrollTop : $targetSection[0].offsetTop - containerOffset }, 500);
// Change background color
$activeSection.removeClass('active');
$targetSection.addClass('active');
}
});
</script>
</body>
</html>
I'm trying to add a class to div when a user scrolls down the page. When they scroll 200px down the page I want a class to be added and then once the user scrolls down 300px I want the class to be removed. Similarly, when the user scrolls back up the page and is 300px from the top, I then want the class to be added until it gets to 200px and then removes the class.
I've tried so many variations but I think I'm approaching it all wrong. Here's a jsfiddle of how far I've gotten so far - http://jsfiddle.net/v8my3sr1/
$(window).on('scroll',function() {
var scroll = $(window).scrollTop();
if (scroll >= 200) {
$(".trigger").addClass("wow");
} else {
$(".trigger").removeClass("wow");
}
});
You condition is incorrect. You should check that scroll value is between 200 and 300
$(window).on('scroll',function() {
var scroll = $(window).scrollTop();
if (300 >= scroll && scroll >= 200) {
$(".trigger").addClass("wow");
} else {
$(".trigger").removeClass("wow");
}
});
$(window).on('scroll',function() {
var scroll = $(window).scrollTop();
if (300 >= scroll && scroll >= 200) {
$(".trigger").addClass("wow");
} else {
$(".trigger").removeClass("wow");
}
});
.container {
height: 2000px;
}
.trigger {
margin-top: 300px;
height: 400px;
}
.wow {
background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="trigger">
<h1>Trigger container</h1>
</div>
</div>
Also you can use .toggleClass() to simplifying code
$(window).on('scroll',function() {
var scroll = $(window).scrollTop();
$(".trigger").toggleClass("wow", 300 >= scroll && scroll >= 200);
});
Try something like this :
$(window).scroll(function(){
var cutoff = $(window).scrollTop();
$(".trigger").each(function(){
if($(this).offset().top + $(this).height() > cutoff){
panel.removeClass('wow');
$(this).addClass('wow');
return false;
}
})
})
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>
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;
});
});