Search code examples
sveltesvelte-3

Bind <svelte:window> to `onbeforeunload`


I was hoping to bind to <svelte:window> but have no luck.

<!-- doesn't work -->
<svelte:window on:beforeunload={() => true} />

<!-- doesn't work -->
<svelte:window on:onbeforeunload={() => true} />

<!-- doesn't work -->
<svelte:window on:beforeUnload={() => true} />

in all instances, window.onbeforeunload is null

I ended up just going with window.onbeforeunload = () => true but was wondering why setting on the element didn't work.


Solution

  • You need to set the event returnValue when using svelte:window

    <script>
    
      function beforeUnload() {
        // Cancel the event as stated by the standard.
        event.preventDefault();
        // Chrome requires returnValue to be set.
        event.returnValue = '';
        // more compatibility
        return '...';
      }
    
    </script>
    
    <svelte:window on:beforeunload={beforeUnload}/>
    

    The reason for this is that writing on:event={handler} in svelte, is equivalent to writing node.addEventListener(event, handler, options)

    It turns out that when attaching beforeunload using addEventListener, then you need to set the event returnValue and/or return a value

    However note that not all browsers support this method, and some instead require the event handler to implement one of two legacy methods:

    • assigning a string to the event's returnValue property
    • returning a string from the event handler.

    Registering the event using window.onbeforeunload only requires a return value