1

I built a component in VueJs/Gridsome for smooth page scrolling using locomotive-scoll. On initial page load or hard page reload it works fine, but not when just changing the route. I tried several ways like adding a key to the component or using the watch method, but nothing seems to work.

CustomScroll.vue

<template>
  <div></div>
</template>

<script>
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);

import LocomotiveScroll from "locomotive-scroll";

export default {
  name: "CustomScroll",
  data() {
    return {
      // x: null,
    };
  },
  methods: {
    scrollMeTo(target, duration) {
      let z = this.x;
      z.scrollTo(target, duration);
    },
    initScroll() {
      const locoScroll = new LocomotiveScroll({
        el: document.querySelector("[data-scroll-container]"),
        smooth: true,
      });

      this.x = locoScroll;

      ScrollTrigger.scrollerProxy("[data-scroll-container]", {
        scrollTop(value) {
          return arguments.length ? locoScroll.scrollTo(value, 0, 0) : locoScroll.scroll.instance.scroll.y;
        },
        getBoundingClientRect() {
          return {
            top: 0,
            left: 0,
            width: window.innerWidth,
            height: window.innerHeight,
          };
        },
        pinType: document.querySelector("[data-scroll-container]").style.transform ? "transform" : "fixed",
      });

      // --- scrollTrigger update, do not move this --- //
      ScrollTrigger.addEventListener("refresh", () => locoScroll.update());
      ScrollTrigger.refresh();
    },
  },
  mounted() {
    this.initScroll();
  },
};
</script>

The Default.vue where the component is referenced:

<template>
  <div class="layout">
    <Header />
    <main>
      <slot />
    </main>
    <CustomCursor />
    <CustomScroll ref="scroller" />
  </div>
</template>

<static-query>
query {
  metadata {
    siteName,
    siteDescription,
    siteUrl
  }
}
</static-query>

<script>
import CustomCursor from "~/components/CustomCursor.vue";
import CustomScroll from "~/components/CustomScroll.vue";
import Header from "~/components/Header.vue";
import Footer from "~/components/Footer.vue";

export default {
  components: {
    CustomCursor,
    CustomScroll,
    Header,
    Footer,
  },
};
</script>
  • Have you considered using the navigation guards, such as beforeRouteUpdate to call the init or refresh function for the scrolling component? – richter Jun 27 '21 at 12:28
  • Idk, I tried so many things already. And it should be something like locoScroll.update() after all content of the new component has been rendered, so I don't know if beforeRouteUpdate would do the trick. beforeRouteUpdate() { locoScroll.update(); }, does nothing – Mark Herpich Jun 27 '21 at 12:42

0 Answers0