Javascript vertical scrolling function - javascript

I am trying to detect a scroll on my page using JavaScript. So that I can change classes and attributes of some elements when user has scrolled certain amount of page. This is my JS function:
function detectScroll() {
var header = document.querySelector(".headerOrig"),
header_height = getComputedStyle(header).height.split('px')[0],
fix_class = "changeColor";
if( window.pageYOffset > header_height ) {
header.classList.add(fix_class);
}
if( window.pageYOffset < header_height ) {
header.classList.remove(fix_class);
}
var change = window.setInterval(detectScroll, 5000);
}
and I am calling it when the page is loaded:
<body onload="detectScroll();">
However, I have this problem - I need to set up a really small interval so that the function gets called and the class is changed immediately. BUT then the page freezes and everything except the JS function works very slowly.
Is there any better way of achieving this in JavaScript?
Thanks for any advice/suggestion.

You are going to want to change a couple things. First, we can use onscroll instead of an interval. But you are also going to want to cache as much as possible to reduce the amount of calculations on your scroll. Even further, you should use requestAnimationFrame (or simply "debounce" in general for older browsers -- see the link). This ensures your work only happens when the browser is planning on repainting. For instance, while the user scrolls the actual scroll event may fire dozens of times but the page only repaints once. You only care about that single repaint and if we can avoid doing work for the other X times it will be all the more smoother:
// Get our header and its height and store them once
// (This assumes height is not changing with the class change).
var header = document.querySelector(".headerOrig");
var header_height = getComputedStyle(header).height.split('px')[0];
var fix_class = "changeColor";
// This is a simple boolean we will use to determine if we are
// waiting to check or not (in between animation frames).
var waitingtoCheck = false;
function checkHeaderHeight() {
if (window.pageYOffset > header_height) {
header.classList.add(fix_class);
}
if (window.pageYOffset < header_height) {
header.classList.remove(fix_class);
}
// Set waitingtoCheck to false so we will request again
// on the next scroll event.
waitingtoCheck = false;
}
function onWindowScroll() {
// If we aren't currently waiting to check on the next
// animation frame, then let's request it.
if (waitingtoCheck === false) {
waitingtoCheck = true;
window.requestAnimationFrame(checkHeaderHeight);
}
}
// Add the window scroll listener
window.addEventListener("scroll", onWindowScroll);

use onscroll instead of onload so you don't need to call the function with an interval.
Your dedectScroll function will be triggered automatically when any scroll appers if you use onscroll
<body onscroll="detectScroll();">

Your function is adding an interval recursively, you should add an event listener to the scroll event this way :
function detectScroll() {
var header = document.querySelector(".headerOrig"),
header_height = getComputedStyle(header).height.split('px')[0],
fix_class = "changeColor";
if( window.pageYOffset > header_height ) {
header.classList.add(fix_class);
}
if( window.pageYOffset < header_height ) {
header.classList.remove(fix_class);
}
}
window.addEventListener("scroll",detectScroll);

Related

Detect new mouse wheel event

I'm using the following event listener to detect mouse wheel and scroll direction:
window.addEventListener('wheel', ({ deltaY }) => {
console.log(deltaY);
if (deltaY > 0) scrollDown();
else if (deltaY < 0) scrollUp();
});
The following happens here:
2 finger touch pad scroll on Macbook triggers the event handler
deltaY keeps logging due to the scroll accelerometer
scrollDown() or scrollUp() keep firing until accelerometer stops
I only want to fire scrollUp and scrollDown once per user interaction. I therefore need to detect a new mouse scroll event, not every mouse scroll events. Is this possible?
I did try a timeout to detect if deltaY was still changing due to the accelerometer, but this wasn't sufficient because if it was still changing, a second user interaction did not trigger scrollUp or scrollDown.
Here's a CodePen of what I'm trying to achieve: https://codepen.io/anon/pen/dQmPNN
It's very close to the required functionality, but if you hammer the mouse wheel hard on the first slide, then try to scroll to the next one immediately, the timeout solution locks it so you have to wait another second or so until the timeout completes and you can continue scrolling.
This is old but I found it when looking for an answer to pretty much the same problem.
I solved the problem for my purposes, so here's my solution in case it helps anyone else.
The problem is really to define what counts as one continuous action. Without something more concrete to work with, it's just a question of timing. It's the time between events that's the key - so the algorithm is to keep accumulating events until there's a certain gap between them. All that then remains is to figure out how big the allowed gap should be, which is solution specific. That's then the maximum delay after the user stops scrolling until they get feedback. My optimum is a quarter of a second, I'm using that as a default in the below.
Below is my JavaScript, I'm attaching the event to a div with the id 'wheelTestDiv' using jQuery but it works the same with the window object, as in the question.
It's worth noting that the below looks for any onWheel event but only tracks the Y axis. If you need more axes, or specifically only want to count events towards the timer when there's a change in deltaY, you'll need to change the code appropriately.
Also worth noting, if you don't need the flexibility of tracking events against different DOM objects, you could refactor the class to have static methods and properties, so there would be no need to create a global object variable. If you do need to track against different DOM objects (I do), then you may need multiple instances of the class.
"use strict";
class MouseWheelAggregater {
// Pass in the callback function and optionally, the maximum allowed pause
constructor(func, maxPause) {
this.maxAllowedPause = (maxPause) ? maxPause : 250; // millis
this.last = Date.now();
this.cummulativeDeltaY = 0;
this.timer;
this.eventFunction = func;
}
set maxPause(pauseTime) {
this.maxAllowedPause = pauseTime;
}
eventIn(e) {
var elapsed = Date.now() - this.last;
this.last = Date.now();
if ((this.cummulativeDeltaY === 0) || (elapsed < this.maxAllowedPause)) {
// Either a new action, or continuing a previous action with little
// time since the last movement
this.cummulativeDeltaY += e.originalEvent.deltaY;
if (this.timer !== undefined) clearTimeout(this.timer);
this.timer = setTimeout(this.fireAggregateEvent.bind(this),
this.maxAllowedPause);
} else {
// just in case some long-running process makes things happen out of
// order
this.fireAggregateEvent();
}
}
fireAggregateEvent() {
// Clean up and pass the delta to the callback
if (this.timer !== undefined) clearTimeout(this.timer);
var newDeltaY = this.cummulativeDeltaY;
this.cummulativeDeltaY = 0;
this.timer = undefined;
// Use a local variable during the call, so that class properties can
// be reset before the call. In case there's an error.
this.eventFunction(newDeltaY);
}
}
// Create a new MouseWheelAggregater object and pass in the callback function,
// to call each time a continuous action is complete.
// In this case, just log the net movement to the console.
var mwa = new MouseWheelAggregater((deltaY) => {
console.log(deltaY);
});
// Each time a mouse wheel event is fired, pass it into the class.
$(function () {
$("#wheelTestDiv").on('wheel', (e) => mwa.eventIn(e));
});
Web page ...
<!DOCTYPE html>
<html>
<head>
<title>Mouse over test</title>
<script src="/mouseWheelEventManager.js"></script>
</head>
<body>
<div id="wheelTestDiv" style="margin: 50px;">Wheel over here</div>
</body>
</html>
Have you tried breaking this out into functions with a flag to check if an interaction has occurred?
For example:
// Create a global variable which will keep track of userInteraction
let shouldScroll = true;
// add the event listener, and call the function when triggered
window.addEventListener('wheel', () => myFunction());
//Create a trigger function, checking if shouldScroll is true or false.
myFunction(){
shouldScroll ? (
if (deltaY > 0) scrollDown();
else if (deltaY < 0) scrollUp();
// Change back to false to prevent further scrolling.
shouldScroll = false;
) : return;
}
/* call this function when user interaction occurs
and you want to allow scrolling function again.. */
userInteraction(){
// set to true to allow scrolling
shouldScroll = true;
}
We can avoid such a situation by delay execution and removing the events in between the delay, refer below example and have added 1000ms as delay which can be modified based on your requirements.
let scrollPage = (deltaY)=>{
console.log(deltaY);
if (deltaY > 0) scrollDown();
else if (deltaY < 0) scrollUp();
};
var delayReg;
window.addEventListener('wheel', ({ deltaY }) => {
clearTimeout(delayReg);
delayReg = setTimeout(scrollPage.bind(deltaY),1000);
});

Why does my scroll function trigger on page load?

I'm trying to create a simple scroll effect where the page header hides when the page scrolls down and reappears on scroll up. The HTML:
<header class="siteHeader">...</header>
...is hidden by applying the CSS class "siteHeader--up."
I'm using jQuery. Here is my code:
$(function () {
var $siteHeader = $('.siteHeader');
var $window = $(window);
// to determine scroll direction. initializes to 0 on page load
var scrollReference = 0;
function fixedHeader () {
var scrollPosition = $window.scrollTop();
// if page is scrolling down, apply the CSS class
if (scrollPosition > scrollReference)
{
$siteHeader.addClass('siteHeader--up');
}
// otherwise, page is scrolling up. Remove the class
else
{
$siteHeader.removeClass('siteHeader--up');
}
// update reference point to equal where user stopped scrolling
scrollReference = scrollPosition
}
$window.scroll(function () {
fixedHeader();
});
});
This works fine for the most part. The problem is when I scroll down the page and then refresh the page. Somehow the scroll function is being triggered. The header will be visible for a moment and then hide (as though the page thinks it's being scrolled down). The function is being triggered on page load (confirmed with a console.log), but I don't understand why, because it's only supposed to fire on scroll.
Can someone help me understand what's going on and how I can prevent it?
Thanks!
That is the expected behavior. When the page is refreshed, the browser remembers the scroll position and it scrolls the page to that position, later on the scroll event is fired.
I think that this could be a workaround to solve your problem:
When the jQuery scroll event is fired you can get the timeStamp property and if this timeStamp is very close to the window.onload timeStamp, surely it can't be an event triggered by the user:
I've used a value of 50 milliseconds, test if it is sufficient, I think that it is.
var startTime = false;
$(function () {
var $siteHeader = $('.siteHeader');
var $window = $(window);
// to determine scroll direction. initializes to 0 on page load
var scrollReference = 0;
function fixedHeader () {
var scrollPosition = $window.scrollTop();
// if page is scrolling down, apply the CSS class
if (scrollPosition > scrollReference)
{
$siteHeader.addClass('siteHeader--up');
}
// otherwise, page is scrolling up. Remove the class
else
{
$siteHeader.removeClass('siteHeader--up');
}
// update reference point to equal where user stopped scrolling
scrollReference = scrollPosition
}
$window.on("load", function (evt) {
startTime = evt.timeStamp;
});
$window.on("scroll", function (evt) {
if(!startTime || evt.timeStamp - startTime < 50) return;
fixedHeader();
});
});
Try Loading the function on window load as well as in the scroll function:
$window.load(function(){
fixedHeader();
});
Or on document ready maybe:
$(document).ready(function () {
fixedHeader();
});
This should trigger and reset the values in the Variables you made and therefore determine whether to set the header to fixed or not, regardless of the scroll position.
Let me know if it works because i'm kinda curious too :)

Javascript fade in doesn't visibly animate

So I've created the following function to fade elements in and passed in a div that I want to fade in which in this case is an image gallery popup that I want to show when a user clicks an image thumbnail on my site. I'm also passing in a speed value (iSpeed) which the timeout uses for it's time value. In this case I'm using 25 (25ms).
I've stepped through this function whilst doing so it appears to be functioning as expected. If the current opacity is less than 1, then it is incremented and it will recall itself after the timeout until the opacity reaches 1. When it reaches one it stops fading and returns.
So after stepping through it, I take off my breakpoints and try to see it in action but for some reason my gallery instantly appears without any sense of fading.
var Effects = new function () {
this.Fading = false;
this.FadeIn = function (oElement, iSpeed) {
//set opacity to zero if we haven't started fading yet.
if (this.Fading == false) {
oElement.style.opacity = 0;
}
//if we've reached or passed max opacity, stop fading
if (oElement.style.opacity >= 1) {
oElement.style.opacity = 1;
this.Fading = false;
return;
}
//otherwise, fade
else {
this.Fading = true;
var iCurrentOpacity = parseFloat(oElement.style.opacity);
oElement.style.opacity = iCurrentOpacity + 0.1;
setTimeout(Effects.FadeIn(oElement, iSpeed), iSpeed);
}
}
}
Here's where I'm setting up the gallery.
this.Show = function (sPage, iImagesToDisplay, oSelectedImage) {
//create and show overlay
var oOverlay = document.createElement('div');
oOverlay.id = 'divOverlay';
document.body.appendChild(oOverlay);
//create and show gallery box
var oGallery = document.createElement('div');
oGallery.id = 'divGallery';
oGallery.style.opacity = 0;
document.body.appendChild(oGallery);
//set position of gallery box
oGallery.style.top = (window.innerHeight / 2) - (oGallery.clientHeight / 2) + 'px';
oGallery.style.left = (window.innerWidth / 2) - (oGallery.clientWidth / 2) + 'px';
//call content function
ImageGallery.CreateContent(oGallery, sPage, iImagesToDisplay, oSelectedImage);
//fade in gallery
Effects.FadeIn(oGallery, 25);
}
Could anyone help me out?
Also, I'm using IE10 and I've also tried Chrome, same result.
Thanks,
Andy
This line:
setTimeout(Effects.FadeIn(oElement, iSpeed), iSpeed);
calls Effects.FadeIn with the given arguments, and feeds its return value into setTimeout. This is exactly like foo(bar()), which calls bar immediately, and then feeds its return value into foo.
Since your FadeIn function doesn't return a function, that would be the problem.
Perhaps you meant:
setTimeout(function() {
Effects.FadeIn(oElement, iSpeed);
}, iSpeed);
...although you'd be better off creating that function once and reusing it.
For instance, I think this does what you're looking for, but without recreating functions on each loop:
var Effects = new function () {
this.FadeIn = function (oElement, iSpeed) {
var fading = false;
var timer = setInterval(function() {
//set opacity to zero if we haven't started fading yet.
if (fading == false) { // Consider `if (!this.Fading)`
oElement.style.opacity = 0;
}
//if we've reached or passed max opacity, stop fading
if (oElement.style.opacity >= 1) {
oElement.style.opacity = 1;
clearInterval(timer);
}
//otherwise, fade
else {
fading = true;
var iCurrentOpacity = parseFloat(oElement.style.opacity);
oElement.style.opacity = iCurrentOpacity + 0.1;
}
}, iSpeed);
};
};
Your code has a lot of problems. The one culpable for the element appearing immediately is that you call setTimeout not with a function but with the result of a function, because Effects.FadeIn will be executed immediately.
setTimeout(function(){Effects.FadeIn(oElement, iSpeed)}, iSpeed);
will probably act as you intend.
But seriously, you probably should not re-invent this wheel. jQuery will allow you to fade elements in and out easily and CSS transitions allow you to achieve element fading with as much as adding or removing a CSS class.
T.J. and MoMolog are both right about the bug: you're invoking the Effects.FadeIn function immediately before passing the result to setTimeout—which means that Effects.FadeIn calls itself synchronously again and again until the condition oElement.style.opacity >= 1 is reached.
As you may or may not know, many UI updates that all take place within one turn of the event loop will be batched together on the next repaint (or something like that) so you won't see any sort of transition.
This jsFiddle includes the suggested JS solution, as well as an alternate approach that I think you may find to be better: simply adding a CSS class with the transition property. This will result in a smoother animation. Note that if you go this route, though, you may need to also include some vendor prefixes.

Javascript - Efficiency for scroll event, run code only once

These if statements are always making me dizzy. If have a page with a header, and a hidden header above that in the markup.
<div id="headerfloat" style="display:none;">
<p>Floated header</p>
</div>
<div id="header">
<p>Header</p>
</div>
The idea is that whenever the page is scrolled down more than 225px, the #headerfloat should appear, and dissapear when topScroll is less than 225px. And I managed to get this working with javascript and jQuery, but when I test it on iPhone, it's very sluggish. And I'm pretty sure it's because the code is run at each scroll event. And even if #headerfloat is visible, the code still executes. Even though it doesn't have to at that point.
So, I need to make sure the code only run once, when it's needed. My first thought was to add and remove classes like .open and .closed to #headerfloat. And run if statements on those during the scroll event. But is that the most efficient way of doing it?
My so far, ugly snippet:
jQuery(window).scroll(function () {
var headerfloat = $("#header_float");
var top = jQuery(window).scrollTop();
if (top > 225) // height of float header
{
if (!$(headerfloat).hasClass("closed")) {
$(headerfloat).addClass("boxshadow", "", 100, "easeInOutQuad").slideDown().addClass("open").removeClass("closed");
}
} else {
$(headerfloat).removeClass("boxshadow", "", 100, "easeInOutQuad").removeClass("closed").slideUp();
}
});
Edit: So after laconbass's awesome response, this is the code I ended up with:
var mainHeader = $('#header')
, top_limit = mainHeader.outerHeight()
, $window = $(window)
;
var header_float = $('#header_float')
bindEvent();
function bindEvent() {
$window.scroll( scrollEvent );
}
function scrollEvent() {
var top = $window.scrollTop();
// avoid any logic if nothing must be done
if ( top < top_limit && !header_float.is(':visible')
|| top > top_limit && header_float.is(':visible')
) return;
// unbind the scroll event to avoid its execution
// until slide animation is complete
$window.unbind( 'scroll' );
// show/hide the header
if ( top > top_limit ) {
header_float.slideDown( 400, bindEvent );
} else {
header_float.slideUp( 400, bindEvent );
}
};
The snippet you started from seems a bit ugly.
I've made one on jsfiddle for your pleasure and reference
I've assumed the following:
you want a fixed positioned header when the page scrolls down (aka fixed header).
fixed headed is a clone of the page main header, with the class fixed.
fixed header is shown when the page scrolls down more than the header height.
fixed header is hidden when the page scrolls up enough to show the main page header.
Performance tips:
cache the jQuery objects to avoid making a new query each time the event handler is executed.
unbind the event handler before the show/hide animations, rebind it after.
on the event handler, return as soon as posible to avoid unnecesary logic. Remember while JavaScript is executed the browser render process is blocked.
var mainHeader = $('header')
, header = mainHeader.clone().addClass('fixed').appendTo('body')
, top_limit = header.outerHeight()
;
bindEvents();
function bindEvents() {
$(window).scroll( scrollEvent );
}
function scrollEvent() {
var top = $(window).scrollTop();
// avoid any logic if nothing must be done
if ( top < top_limit && !header.is(':visible')
|| top > top_limit && header.is(':visible')
) return;
// unbind the scroll event to avoid its execution
// until slide animation is complete
$(window).unbind( 'scroll' );
// show/hide the header
if ( top > top_limit ) {
header.slideDown( 400, bindEvents );
} else {
header.slideUp( 400, bindEvents );
}
};
<header>
<h1>Awesome header</h1>
</header>
<div>
<!-- the page content -->
</div>
/* the real code needed */
header.fixed {
display: none;
position: fixed;
top: 0;
}
two way:
1,on scroll,and if you have done your want, remove the scroll event.
2,var a variable,default is false, on scroll, if the variable is false,to do you want,and set the variable to true; if the variable is true already, do nothing(or others you want)

How to detect/disable inertial scrolling in Mac Safari?

Is there a way to disable or detect that wheel events are from the "inertia" setting on a Mac?
I'd like to be able to tell the difference between real events and the others...or disable that kind of scrolling for a particular page.
I found a solution that works really well for this. Below is some pasted code from my project. It basically comes down to this logic:
A scroll event is from a human when ANY ONE of these conditions are true:
The direction is the other way around than the last one
More than 50 milliseconds passed since the last scroll event (picked 100ms to be sure)
The delta value is at least as high as the previous one
Since Mac spams scroll events with descreasing delta's to the browser every 20ms when inertial scrolling is enabled, this is a pretty failsafe way. I've never had it fail on me at least. Just checking the time since the last scroll won't work because a user won't be able to scroll again if the "virtual freewheel" is still running even though they haven't scrolled for 3 seconds.
this.minScrollWheelInterval = 100; // minimum milliseconds between scrolls
this.animSpeed = 300;
this.lastScrollWheelTimestamp = 0;
this.lastScrollWheelDelta = 0;
this.animating = false;
document.addEventListener('wheel',
(e) => {
const now = Date.now();
const rapidSuccession = now - this.lastScrollWheelTimestamp < this.minScrollWheelInterval;
const otherDirection = (this.lastScrollWheelDelta > 0) !== (e.deltaY > 0);
const speedDecrease = Math.abs(e.deltaY) < Math.abs(this.lastScrollWheelDelta);
const isHuman = otherDirection || !rapidSuccession || !speedDecrease;
if (isHuman && !this.animating) {
this.animating = true; // current animation starting: future animations blocked
$('.something').stop().animate( // perform some animation like moving to the next/previous page
{property: value},
this.animSpeed,
() => {this.animating = false} // animation finished: ready for next animation
)
}
this.lastScrollWheelTimestamp = now;
this.lastScrollWheelDelta = e.deltaY;
},
{passive: true}
);
There's one caveat by the way: Mac also has acceleration on the scrolling, i.e.: at first, the delta value is higher for each successive event. It seems like this does not last more than 100ms or so though. So if whatever action/animation you are firing as a result of the scroll event lasts at least 100ms and blocks all other actions/animations in the meantime, this is never a problem.
Yes and no.
You can use touchdown/up, and scroll as events to look for the page moving about but those won't trigger if the OS is doing an inertial scroll. Fun, right?
One thing that you can continually detect, however, is window.pageYOffset. That value will keep changing while an inertial scroll is happening but won't throw an event. So you can come up with a set of timers to keep checking for an inertial scroll and keep running itself until the page has stopped moving.
Tricky stuff, but it should work.
Oh how is this issue killing me :/
I'm in the process of creating "endless" scrolling large file viewer.
To make situation worse, this editor is embedded in page that has its own scroll bar, because its bigger than one screen.
U use overflow-x scroll for horizontal scroll, but for vertical scroll i need current line highlighter (as seen in most modern IDEs) so i'm using jquery mousewheel plugin, and scrolling moving content for line height up or down.
It works perfectly on ubuntu/chrome but on MacOS Lion/Chrome sometimes, and just sometimes,
when you scroll, it doesn't prevent default scroll on the editor element, and event propagates "up" and page it self starts to scroll.
I cant even describe how much annoying that is.
As for inertial scroll it self, i successfully reduced it with two timers
var self = this;
// mouse wheel events
$('#editorWrapper').mousewheel(function (event, delta, deltax, deltay) {
self._thisScroll = new Date().getTime();
//
//this is entirely because of Inertial scrolling feature on mac os :(
//
if((self._thisScroll - self._lastScroll) > 5){
//
//
// NOW i do actual moving of content
//
//
self._lastScroll = new Date().getTime();
}
5ms is value i found to have most natural feel on my MacBook Pro, and you have to scroll mouse wheel really fast to catch one of those..
Even still, sometimes on Mac listener on mac wrapper doesn't prevent default, and page scrolls down.
Well, (I might be wrong), I think that the "inertia" settings on the Mac are all computed by the system itself, the browser, or any program for that matter would just think that the user is scrolling quickly, rather than slowing down.
I'm not sure about other browsers, but the following event fires during inertial scroll on my Chrome, FF, Safari (mac):
var mousewheelevt=(/Firefox/i.test(navigator.userAgent))? "DOMMouseScroll" : "mousewheel";
function scrollEE (e) {
console.log(e);
}
window.addEventListener(mousewheelevt, scrollEE, false);
I had a big problem with an object animating based on scroll position after the scroll had completed, and the inertial scroll was really messing me around. I ended up calculating the velocity to determine how long the inertial scroll would last and used that to wait before animating.
var currentY = 0;
var previousY = 0;
var lastKnownVelocity = 0;
var velocityRating = 1;
function calculateVelocity() {
previousY = currentY;
currentY = $('#content').scrollTop();
lastKnownVelocity = previousY - currentY;
if (lastKnownVelocity > 20 || lastKnownVelocity < -20) {
velocityRating = 5;
} else {
velocityRating = 1;
}
}
$('#content').scroll(function () {
// get velocity while scrolling...
calculateVelocity();
// wait until finished scrolling...
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function() {
// do your animation
$('#content').animate({scrollTop: snapPoint}, 300);
}, 300*velocityRating)); // short or long duration...
});
There's a library that solves this problem.
https://github.com/d4nyll/lethargy
After installing it, use it like this:
var lethargy = new Lethargy();
$(window).bind('mousewheel DOMMouseScroll wheel MozMousePixelScroll', function(e){
if(lethargy.check(e) === false) {
console.log('stopping zoom event from inertia')
e.preventDefault()
e.stopPropagation();
}
console.log('Continue with zoom event from intent')
});
Following your instructions with my type of code, I had to set timeout of 270ms on each action activated by scroll to get it all smooth, so if anyone is using something similar to me here is my example if not ignore it, hope it will help you.
//Event action
function scrollOnClick(height) {
$('html').animate({
scrollTop: height
}, 'fast');
return false;
};
// Scroll on PC
let timer = false;
$(window).on('mousewheel', function (event) {
if(timer != true) {
var heightWindow = $(window).height();
var heightCurrent = $(window).scrollTop();
if (event.originalEvent.wheelDelta >= 1) {
if (heightWindow >= heightCurrent) {
timer= true;
scrollOnClick(0)
setTimeout(function (){
timer = false;
},270);
}
} else {
if (heightCurrent < heightWindow) {
timer= true;
scrollOnClick(heightWindow)
setTimeout(function (){
timer = false;
},270);
}
}
}
});

Categories

Resources