Skip to content

Instantly share code, notes, and snippets.

@SamJakob
Created October 22, 2018 17:10
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save SamJakob/c9175a4c2440e1b14b0b8cf7d99d2d24 to your computer and use it in GitHub Desktop.
Save SamJakob/c9175a4c2440e1b14b0b8cf7d99d2d24 to your computer and use it in GitHub Desktop.
A vue-js supported smooth-scroll module based on a Stack Overflow answer by Manuel Otto.
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
Copy link
Author

@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);

@joeljose24
Copy link

@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! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment