The problem
In SvelteKit, I am trying to disable and enable scroll when my side menu is opened. To do that, I am trying to utilize the {open} variable that is bound to my menu icon with bind:open={open}.
I want to trigger the function enableScroll() when open is true, and trigger the function disableScroll() when open is false.
Both functions work fine. The {open} variable is true when I expect it to, and false when I expect it to when I use console.log().
The problem is that my if-block doesn't respond to {open} changing.
What I've tried
Currently, my code looks like this:
$: if (open === true) {
onMount(() => {
disableScroll()
})
} else if (open === false) {
onMount(() => {
enableScroll()
})
}
Perhaps I'm using onMount() wrongly? Or somehow I need to change my if statement to make it properly reactive / fix it some other way? I would gladly appreciate some help! Thank you.
onMount
only queues a function to run once, when the component is mounted. So running onMount(() => { disableScroll() })
will not run disableScroll
if the component has already been rendered -- any subsequent changes to open
will not have any affect. This is why your code doesn't work.
However, you do need to do something to prevent your scroll code from running on the server, since window
isn't available there. In SvelteKit, you can determine whether you're in the browser by using the browser import from $app/env
. This will tell you if it's safe to access browser-only APIs on the document or window. So, you could do something like the following:
<script>
import { onMount } from 'svelte';
import { browser } from '$app/env';
let open;
let scrollTop = null;
let scrollLeft = null;
function disableScroll() {
if (browser) {
scrollTop =
window.pageYOffset || window.document.documentElement.scrollTop;
scrollLeft =
window.pageXOffset || window.document.documentElement.scrollLeft,
window.onscroll = function() {
window.scrollTo(scrollLeft, scrollTop);
}};
}
function enableScroll() {
if (browser) {
window.onscroll = function() {};
}
};
$: if (open) {
disableScroll();
} else {
enableScroll();
}
</script>