ashthornton / asscroll

Ash's Smooth Scroll 🍑
MIT License
946 stars 27 forks source link

Asscroll + Highway.js #36

Closed paullangton closed 3 years ago

paullangton commented 3 years ago

Hi Ash,

This one might be a little difficult to recreate so will try explain the best I can.

I'm trying to use Assroll with es modules and highway js where I have an init and destroy function in my scroll.js file. Asscroll setup is default with all the css. I've even tried the disable native scrollbar method.

In the highway renderer.js file I call the two functions as normal. destroy on leave, init on completed.

However, when the transition is in progress and you scroll (both mouse and touch pad) I get a jump in content. it perfectly scrolls but the content isn't visible until after a few seconds when it catches up to the current scroll position.

I tried the same setup with locomotive scroll and works perfectly. When you inspect the element you can see that It destroys the scrollbar and inits it after page transition completed.

With Asscroll the scrollbar is never destroyed which I think is causing the problem so if you try to scroll between the transitions you can see the s'show' class being added.

All asscroll setup is standard.

Let me know if you need more information.

ashthornton commented 3 years ago

Hey @paullangton could you paste in your code so I can see exactly what you're doing? As in your Highway onLeave() and onEnterCompleted() functions?

I use Highway in a lot of projects and I've never encountered this problem.

paullangton commented 3 years ago

Of course, here is the scroll.js have simplified it, followed by the renderer.js - I've put destroy in both onLeave() and onLeaveCompleted

Note, all components are called into a components index.js and where scroll is being called into the renderer.js file this will usually inti and destroy all the ones inside the renderer html tags.

Let me know if you need anything else.

// Scroll.js import ASScroll from '@ashthornton/asscroll'

export default class Scroll { constructor() { this.scroll = new ASScroll({ element: '.o-site_wrapper', innerElement: '.o-scroll', customScrollbar: true }); }

init() {
    this.scroll.enable();
}

destroy() {
    this.scroll.disable();
}

}

// Renderer.js // components import Scroll from '../components/scroll/scroll';

class Renderer extends Highway.Renderer { onEnter() {

    }

    onEnterCompleted() {
          this.scroll = new Scroll();
          this.scroll.init();
    }

    onLeave() {

    }

    onLeaveCompleted() {
          this.scroll.destroy();
    }

}

// export export default Renderer;

ashthornton commented 3 years ago

It looks like you're initialising a new ASScroll instance every time onEnterCompleted() is run. You want to have only one instance which you then call enable() and disable() on.

There's various ways of setting up a Highway renderer to run code only once on site load, but the easiest way might be to make the ASScroll instance outside of your renderer:

const asscroll = new ASScroll()
const highway = new Highway()
ashthornton commented 3 years ago

You can set up a 'first load' function within a Highway renderer by overriding the setup() function in the Renderer class:

class DefaultRenderer extends Highway.Renderer {
    onFirstLoad() {
        this.scroll = new ASScroll()
        this.onEnter()
        this.onEnterCompleted()
    }

    setup() {
        this.onFirstLoad()
    }
}

I do this on every project as it gives better control over that initial site load

paullangton commented 3 years ago

Thanks for your reply Ash.

I thought initialising the plugin after onEnterCompleted() allowed it to re-calculate the new page height.

I'v had a quick play with the DefaultRenderer extends Highway.Renderer but just can't seem to get it to initialise again after the page transition.

First time using highway.js. So will dig a bit deeper into the docs.

I note you have a highway-kit which seems to be following what you are saying so will check that out too.

ashthornton commented 3 years ago

I thought initialising the plugin after onEnterCompleted() allowed it to re-calculate the new page height.

Calling .enable() re-calculates the page height by default so you don't need to re-init.

I note you have a highway-kit which seems to be following what you are saying so will check that out too.

That is pretty out-dated but I think some of the core concepts are in there.

Let me know how you get on and whether or not it fixes your original issue.

paullangton commented 3 years ago

Hi Ash - got it working - feel free to close this.

I just removed asscroll out of it's own scroll.js file and called it directly into my components.js file where I use the enable() and disable()

That way (as you said) i'm only creating one instance of asscroll. Has fixed the page jump.

I look further into your suggestion with the firstload. Good concept.

Thank your help and quick repsonses.

ashthornton commented 3 years ago

No worries @paullangton, glad you got it working :)