-
-
Save SamJakob/c9175a4c2440e1b14b0b8cf7d99d2d24 to your computer and use it in GitHub Desktop.
const SmoothScroll = (target, speed, smooth) => { | |
if (target === document) | |
target = (document.documentElement || document.body.parentNode || document.body) // cross browser support for document scrolling | |
let moving = false; | |
let pos = target.scrollTop; | |
target.addEventListener('mousewheel', scrolled, false) | |
/* target.addEventListener('DOMMouseScroll', scrolled, false) */ | |
function scrolled(e) { | |
e.preventDefault(); // disable default scrolling | |
let delta = e.delta || e.wheelDelta; | |
if (delta === undefined) { | |
//we are on firefox | |
delta = -e.detail; | |
} | |
delta = Math.max(-1, Math.min(1, delta)) // cap the delta to [-1,1] for cross browser consistency | |
pos += -delta * speed | |
pos = Math.max(0, Math.min(pos, (target.scrollHeight - target.clientHeight) + (smooth * 2))) // limit scrolling | |
if (!moving) update() | |
} | |
function update() { | |
moving = true | |
let delta = (pos - target.scrollTop) / smooth; | |
delta -= 1; | |
if(pos - target.scrollTop === smooth * 2) | |
delta = 0; | |
target.scrollTop += delta | |
if (Math.abs(delta) > 0.5) | |
requestFrame(update) | |
else | |
moving = false | |
} | |
var requestFrame = function() { // requestAnimationFrame cross browser | |
return ( | |
window.requestAnimationFrame || | |
window.webkitRequestAnimationFrame || | |
window.mozRequestAnimationFrame || | |
window.oRequestAnimationFrame || | |
window.msRequestAnimationFrame || | |
function(func) { | |
window.setTimeout(func, 1000 / 50); | |
} | |
); | |
}() | |
} | |
export default SmoothScroll; |
<template> | |
... | |
</template> | |
<script> | |
import SmoothScroll from 'assets/js/smoothscroll'; | |
export default { | |
mounted () { | |
if(!window.smoothScroll){ | |
window.smoothScroll = SmoothScroll(document, 120, 12); | |
} | |
} | |
} | |
</script> |
@SamJakob not exactly sure what you mean by moving the variable outside the function or to a different scope.. My exact scenario is I have a main webpage with a bunch of components. As the main webpage loads, if smoothscroll.js isn't in use, it calls the function. Beyond that, there is a component at a point on the webpage within which I call the smoothscroll.js function to slow it down.
@joeljose24
So if you see on line 1, the function is defined as const SmoothScroll = (target, speed, smooth) => {
I'd suggest taking speed out of the function arguments, so it's const SmoothScroll = (target, smooth) => {
and just defining speed
as a variable outside of the function. e.g.,
// Set the initial speed.
let speed = 120;
export function setSpeed(newScrollSpeed) {
speed = newScrollSpeed;
}
const SmoothScroll = (target, smooth) => {
// .. rest of the function from above (by not specifying speed as an argument it'll use the one defined above which
// will let us call setSpeed to change it)
}
export default SmoothScroll;
Then in the Vue example, you might call it like so:
import SmoothScroll, { setScrollSpeed } from 'assets/js/smoothscroll';
// ...
mounted () {
if(!window.smoothScroll){
window.smoothScroll = SmoothScroll(document, 12);
}
}
// ...
Then, when you want to change the scroll speed like so:
setScrollSpeed(240);
@SamJakob hey sam, I figured a workaround for this, I'm just disabling window scroll for specific points and enabling it after a time out.
Regardless, this solution still helped me solve a bug that I had because of the scroll disabling so, thank you so much for taking the time to answer my doubt! :)
@joeljose24 Thank you :)
Have you tried moving the
speed
variable outside of the function or moving it to the scope where you change the speed?