Prevent <dialog> from closing on keydown Esc in Chrome
Asked Answered
A

3

21

Google Chrome closes <dialog> elements when Esc is pressed. Seems to be reacting to keydown.

Firefox does not. This is the expected behavior, as closing on any key press is easy to implement.

How to make Google Chrome leave dialogs open on Esc?

Please see fiddle https://jsfiddle.net/zeqo7kaf/1/

I have implemented window's, document's, body's, dialog's key events (up, down and pressed) to prevent propagation, however it seems to me that this is above dom events.

(in order to see dialogs in Firefox, go to about:config and set property dom.dialog_element.enabled to true).

Apocarpous answered 3/4, 2020 at 22:7 Comment(0)
E
51

You can try to use cancel event: MDN

dialog.addEventListener('cancel', (event) => {
    event.preventDefault();
});

Modified JSFiddle: https://jsfiddle.net/7et3hf8p/

Electorate answered 3/4, 2020 at 22:25 Comment(1)
The cancel event documentation is now under HTMLElement, which is a bit unfortunate because the page for HTMLDialogElement does not have a good example for it, and only lists the close event that seems to fire only after the dialog is closed. Also in Chrome, pressing Esc twice still seems to close it even after preventing... In Firefox it works as expectedPlumose
K
1

React Solution

function Dialog() {
  return <dialog onCancel={event => event.preventDefault()} />
}
Keppel answered 18/4 at 22:4 Comment(0)
S
0

React Solution

Since the cancel/close events fire after the fact, I got this working by adding a keydown listener to the document itself.

const handleKeyDown = (e) => {
  if (e.key !== 'Escape') return;
  if (!allowDialogDismiss) e.preventDefault();
}

useEffect(() => {
  document.addEventListener('keydown', handleKeyDown);

  return () => {
    document.removeEventListener('keydown', handleKeyDown);
  };
}, [allowDialogDismiss]);

The dialog doesn't dismiss on ESC key press anymore.


I have a text input inside the dialog and pressing ESC by mistake would mean losing the text input before it is saved. This worked. I change the allowDialogDismiss state depending on the input's text.

Steal answered 10/1 at 4:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.