smooth scrolling div by div - javascript

i've added this script that scroll down 100% with mouseweel at once
$(document).ready(function () {
var divs = $('.mydiv');
var dir = 'up'; // wheel scroll direction
var div = 0; // current div
$(document.body).on('DOMMouseScroll mousewheel', function (e) {
if (e.originalEvent.detail > 0 || e.originalEvent.wheelDelta < 0) {
dir = 'down';
} else {
dir = 'up';
}
// find currently visible div :
div = -1;
divs.each(function(i){
if (div<0 && ($(this).offset().top >= $(window).scrollTop())) {
div = i;
}
});
if (dir == 'up' && div > 0) {
div--;
}
if (dir == 'down' && div < divs.length) {
div++;
}
//console.log(div, dir, divs.length);
$('html,body').stop().animate({
scrollTop: divs.eq(div).offset().top
}, 200);
return false;
});
$(window).resize(function () {
$('html,body').scrollTop(divs.eq(div).offset().top);
});
});
But i need to add something on it so the scrolling look smooth , how can i do that ?
Fiddle

You can either specify a duration for your animate function or an easing function to have a different animation behavior.
You can find easing functions and instruction to use theme here :
jQuery Easing Plugin

SOLUTION:
#user3127499 already provided you a working FIDDLE.
He changed the time to 1000 from 100
$('html,body').stop().animate({
scrollTop: divs.eq(div).offset().top
}, 1000);
And added a 1000 delay here:
$('html,body').scrollTop(divs.eq(div).offset().top.delay(1000));
There is a plugin for that:
You will counter many other challenges while recreating the wheel, why don you you simply use this plugin named Scroll Section.
DEMO

Related

How can I control the mouse scroll event and after that do an animation on the html, body?

I'm facing a very strange error, which is animation on body during mouse scroll. I think its happening because of the jQuery event window.scroll. I have tried a lot of things like unbinding of animation on mouse scroll, but nothing works. Below is my code.
$(document).on("scroll", function () {
var lastScrollTop = 0;
var windowHeight = $(window).scrollTop();
var seccion1 = $("#seccion1").height();
var seccion2 = $("#seccion2").offset().top;
var alturaseccion2 = $("#seccion2").height();
//this function returns in which section is the user with the scroll
var localizacion = comprobarSeccion(seccion1, seccion2);
if (windowHeight > lastScrollTop) {
// down scroll
console.log("scrollabajo");
if (localizacion == 1) {
$("html, body").animate({
scrollTop: $("#seccion2").offset().top
}, 2);
$(document).bind("scroll");
} else if (localizacion == 2) {
if (windowHeight >= ((alturaseccion2 * 0.80) + seccion2) && windowHeight <= (alturaseccion2 + seccion2)) {
} else {
}
}
} else {
// up scroll
console.log("scrollarriba");
}
lastScrollTop = windowHeight;
});
ยดยดยด
I'm not sure what you are trying to accomplish, but if your trying to trigger an event with a specific scroll value you can use the code below
$(window).scroll(function () {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
alert("scroll is greater than 500 px)
} else if(scroll==500){
alert("scroll has hit 500px");
}
});

Getting pixel amount of Scrolling in an Overflow Hidden Page

I wish to be able to toggle a class for the body when there is a large amount of scroll in the page, but there is a catch: its a full-sized, hidden overflow, single page.
I tried the simple:
if ($(window).scrollTop() > 1000){
$('body').addClass( "endScroll");
}
else {
$('body').removeClass("endScroll");
}
I tried this method to add the class endScroll after the page has been scrolled after 1000 pixels, however, it does not work because since it is a single screen with overflow hidden, there is no actual scroll from top. (To better explain, there is an animation going on while the user scrolls)
So I tried this method:
$(document).bind('mousewheel', function(e) {
var delta = e.originalEvent.wheelDelta;
if (delta < 0) {
$('body').addClass("endScroll");
} else if (delta > 0) {
$('body').removeClass("endScroll");
}
});
While it actually works, adding the class, it does as soon as the user scroll once. I can't figure a way to make it toggle the class after 1000 pixels have been scrolled.
Thank you in advance!
EDIT: I think this is closer to what you're looking for. You need a tracking variable to see how much the user has scrolled:
var scrollVal = 0;
$(document).bind('mousewheel', function(e) {
scrollVal += e.originalEvent.wheelDelta;
if (scrollVal > 0) scrollVal = 0;
console.log(scrollVal);
if (scrollVal < -1000) {
$('body').addClass( "endScroll");
}else {
$('body').removeClass("endScroll");
}
});
EDIT 2: Firefox compatibility:
var scrollVal = 0;
var mousewheelevt=(/Firefox/i.test(navigator.userAgent))? "DOMMouseScroll" : "mousewheel";
$(document).bind(mousewheelevt, function(e) {
var offset = -1 * e.originalEvent.wheelDelta;
if (mousewheelevt == "DOMMouseScroll"){
offset = e.originalEvent.layerY - e.originalEvent.clientY;
}
scrollVal += offset;
if (scrollVal < 0) scrollVal = 0;
console.log(scrollVal);
if (scrollVal > 1000) {
$('body').addClass( "endScroll");
}else {
$('body').removeClass("endScroll");
}
});
Just scroll it to 1000px and see the background will be red if you scroll up it will be again black
$(window).on("scroll", function() {
if($(window).scrollTop() > 1000){
$(".scroll-div").addClass('scroll-div-red');
}
else{
$(".scroll-div").removeClass('scroll-div-red');
}
});
.scroll-div{
background:#000;
height:1500px;
overflow:hidden;
}
.scroll-div-red.scroll-div{
background:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="scroll-div">
</div>

section snap to window (firefox issue)

I have written a simple custom section snapping script, works great in chrome and safari, but after nothing happens in firefox...
What it is does:
When scrolling stops it checks the direction and location of each secrion... if the top of a section is within a certain range either go to the top of the page or bottom. (scroll directions is also checked). Also, it accounts for the height of a fixed header. Like I said works in Chrome and Safari. Any ideas what's wrong?
$( document ).ready(function() {
var animating = false;
var mainHeader = $('#main-header');
var items = $("section");
var lastOffset = 0;
var scrollDir = 'none';
$(window).scroll(function() {
var windowHeight = $(this).height();
var currOffset = $(this).scrollTop();
var headerHeight = mainHeader.outerHeight();
if (currOffset > lastOffset) {
scrollDir = 'down';
} else {
scrollDir = 'up';
}
lastOffset = currOffset;
clearTimeout($.data(this, 'scrollTimer'));
if (!animating) {
$.data(this, 'scrollTimer', setTimeout(function() {
items.each(function(key, value) {
var currentItem = $(value);
var sectionOffset = currentItem.offset().top;
var sectionDist = sectionOffset - currOffset;
if ( scrollDir === 'up' && sectionDist > windowHeight*0.15 && sectionDist < windowHeight ) {
animating = true;
$('body').animate( { scrollTop: sectionOffset-windowHeight + 'px' }, 250);
setTimeout(function() { animating = false; }, 300);
return false;
}
else if ( scrollDir === 'down' && sectionDist < windowHeight*0.85 && sectionDist > 0 ) {
animating = true;
$('body').animate( { scrollTop: sectionOffset-headerHeight + 'px' }, 250);
setTimeout(function() { animating = false; }, 300);
return false;
}
});
}, 200));
}
});
});
Found the answer here...
Animate scrollTop not working in firefox
Firefox places the overflow at the html level, unless specifically styled to behave differently.
To get it to work in Firefox, use
$('body,html').animate( ... );

Jquery slow reaction time

I try to use the jQuery for my header animation, the animation slows down after I added:
else if (headeranimated && $(this).scrollTop() > 1200)
else if (headeranimated2 && headeranimated && $(this).scrollTop() < 1000)
I have to wait a couple of seconds for the second part of animation. Is there anything wrong with this code?
Thank you
// header animation
var headeranimated2 = false;
var headeranimated = false;
var headeranimated3 = false;
$(window).scroll(function() {
if ($(window).width() > 800) {
if (!headeranimated && $(this).scrollTop() > 500) {
$('#headerpattern').animate({
left: "-40%"
}, 800);
headeranimated = true;
} else if (headeranimated && $(this).scrollTop() > 1200) {
$('#headerpattern').animate({
top: "-20%"
}, 200);
headeranimated2 = true;
} else if (headeranimated2 && headeranimated && $(this).scrollTop() < 1000) {
$('#headerpattern').animate({
top: "0"
}, 200);
headeranimated2 = false;
headeranimated3 = true
} else if (headeranimated3 && !headeranimated2 && $(this).scrollTop() < 400) {
$('#headerpattern').animate({
left: "0"
}, 800);
headeranimated = false;
headeranimated3 = false;
}
} else {
if (!headeranimated && $(this).scrollTop() > 500) {
$('#headerpattern').animate({
top: "-8%"
}, 1200);
headeranimated = true;
} else if (headeranimated && $(this).scrollTop() < 400) {
$('#headerpattern').animate({
top: "0"
}, 800);
headeranimated2 = false;
}
}
});
well.. you are calling the scroll listener which occurs evry moment while you are scrolling. but you also play an animation which is relatevly slow to scroll. when you call the scroll listener by scrolling, you create multiple nimations calls which try to play all at once (and that is why it slows down the ui).
the solution: if animation still played - don't scroll
var animScroll;
$(window).scroll(function()
{
if (animScroll) return;
if ($(window).width() > 800)
{
if (!headeranimated && $(this).scrollTop() > 500)
{
animScroll = true;
$('#headerpattern').animate({ left: "-40%"}, 800, function()
{
animScroll = false;
});
headeranimated = true;
}
// rest of code
A scroll even is an event the is emitted continuously while scrolling, so it will be triggered multiple times a second while you are scrolling.
Whenever you call .animate for an element, the animation is added to a queue. And the animations are executed one after the other, in the order they where added to the queue. As your animations have a duration of in a range of 200 to 1200 you might result in an animation queue that has a duration of several seconds.
One solution would be to call .stop() before you call .animate:
$('#headerpattern').stop().animate(....)
But this might break your desired effect.
Another solution would be to check if there is an animation that is currently running and if so, then do not start a new animation. But this will have some kind of stop and go or delay effect.

Javascript scroll to element on scroll

I searched very long but haven't found a soulution yet.
I want to scroll to the next element on scroll.
$(window).load(function(){
var scroll = false;
$(function() {
//Create an Array
var sites = $('.site');
var position = 0; //Start Position
var next = $('#next');
var lastScrollTop = 0;
$(window).scroll(function(event){
if(scroll == false){
scroll = true;
$(document).off('scroll');
var st = $(this).scrollTop();
if (st > lastScrollTop){
if (position !== sites.length - 1) {
scrollToPosition(sites[position += 1]),5000;
}
} else {
if (position !== 0) {
scrollToPosition(sites[position -= 1]),5000;
}
}
lastScrollTop = st;
}
});
})
function scrollToPosition(element) {
if (element !== undefined) {
scrollToElement($(element).attr('id'));
}
}
function scrollToElement(selector, time, verticalOffset) {
time = typeof(time) != 'undefined' ? time : 500;
verticalOffset = typeof(verticalOffset) != 'undefined' ? verticalOffset : 0;
selector = "#" + selector;
var element = $(selector);
offset = element.offset();
offsetTop = offset.top + verticalOffset;
$('html, body').animate({
scrollTop: offsetTop
}, time);
scroll = false;
}
});
the html has many of these with different ids
<div id="test" style="width:100%; height:100vh;" class="site">
</div>
So the containers are fullscreen hight. and when the user scrolls a bit he should get to the next container.
At the moment it scrolls till the end and or more.
It would help if you could create an example in jsFiddle or CodePen, but the first thing I would do is stop any current jQuery animations before launching new ones:
$('html, body').stop().animate({
scrollTop: offsetTop
}, time);
You should keep in mind that scroll handler is executed many times when user is scrolling.
Also, unrelated - your scrollToPosition calls have brackets at the wrong place and should probably be like this:
scrollToPosition(sites[position += 1], 5000);
Edit:
Another thing that might cause problems - you should unset the 'scroll' flag/variable only when the animation has finished, something like this:
$('html, body').stop().animate({
scrollTop: offsetTop
}, time, function () {
scroll = false;
});

Categories