js-integration-examples
js-integration-examples copied to clipboard
Add preventClose
class PreventClose extends HTMLElement {
// set up events
connectedCallback() {
// disable on localhost for david's sanity
if (window.location.host.includes("localhost")) {
return;
}
this.beforeUnloadListener = (event) => {
event.preventDefault();
return (event.returnValue =
"Are you sure you want to exit? There are unsaved changes.");
};
addEventListener("beforeunload", this.beforeUnloadListener, {
capture: true,
});
}
disconnectedCallback() {
removeEventListener("beforeunload", this.beforeUnloadListener, {
capture: true,
});
}
}
customElements.define("prevent-close", PreventClose);
This looks like an example of something that should not be done as a Custom Element because it's not actually extending HTMLElement. The web component is being used as a convenience for adding arbitrary javascript via the DOM, it's being added to the DOM, but it doesn't actually have any reason to be in the DOM.
Why not use a port instead?
How web components was originally envisioned was as leaf-node or light-DOM-using components
Following arguments for declaring this behavior in the DOM:
- head tags are in the DOM, we can control the title from the view. The line here is blurry
- using the port and tracking the state of the outside world requires a lot of glue code and data massaging if you have a big view
- the knowledge about what needs to be saved before losing it is often available in the view "You have unsaved changes, click here to save". So why not declare the behavior there?