Tema representativo de entrevista

Entrevista de Frontend: ¿Cómo debe closedby de dialog controlar el cierre?

FrontendDifícil
Equipo editorial de Offer.ccPublicado Actualizado

Pregunta

Diseñe un diálogo HTML para una confirmación destructiva con un formulario validado. Compare closedby=none, closerequest y any; explique showModal frente a show, la Popover API, el foco, los motivos de cierre y los fallbacks.

Planteamiento y contexto

Una consola de administración necesita una confirmación destructiva y un formulario de motivo. Algunos flujos deben cerrarse únicamente mediante una acción explícita; otros pueden cerrarse con Escape o un clic exterior. Diseñe la política de cierre del elemento dialog nativo para las rutas de teclado, táctiles y de validación.

MDN define los valores de closedby none, closerequest y any: solo mecanismos del desarrollador, solicitudes de cierre de la plataforma más mecanismos del desarrollador, o los tres mecanismos. Los diálogos modales usan showModal(); los diálogos no modales usan show().

Qué está evaluando el entrevistador

El candidato debe mapear el riesgo de negocio a la política de cierre, distinguir los diálogos modales de los popovers y explicar Escape, el descarte ligero (light dismiss), close(), requestClose(), method="dialog", el foco inicial, la restauración del foco y la validación de formularios.

Preguntas de clarificación para hacer primero

  • ¿Puede descartarse accidentalmente una confirmación destructiva y deben conservarse los datos no guardados?
  • ¿Escape o un clic exterior equivalen a cancelar, o requieren otra confirmación?
  • ¿Debe un botón de cancelar omitir la validación de campos obligatorios?
  • ¿Deben los navegadores no compatibles ofrecer un comportamiento de cierre idéntico?
  • ¿A dónde debe regresar el foco cuando se cierra el diálogo?

Estructura de respuesta en 30 segundos

“Para acciones destructivas utilizo showModal() con closedby="closerequest", o none para la confirmación más estricta, además de botones explícitos de cancelar y confirmar. Un panel informativo de bajo riesgo puede usar any u popover="auto". Un formulario con method="dialog" devuelve un valor; un botón de cancelar puede usar formnovalidate cuando deba omitir la validación. Establezco un foco inicial intencional y restauro el foco al elemento activador. La detección de capacidades proporciona un fallback con botones explícitos y manejo manual del teclado.”

Análisis detallado paso a paso

Paso 1: Elegir entre modal o no modal

showModal() hace que el resto del documento sea inerte y se adapta a confirmaciones destructivas o tareas obligatorias. show() deja la página interactiva para un panel auxiliar. Alternar únicamente el atributo open no establece la semántica modal de foco ni de fondo.

Paso 2: Mapear el riesgo a closedby

closedby="none" solo permite el cierre definido por el desarrollador y es adecuado para confirmaciones irreversibles. closerequest también acepta Escape o una solicitud de cierre de la plataforma. any añade el descarte ligero por clic exterior y se adapta a información de bajo riesgo.

html
<dialog id="delete-dialog" closedby="closerequest">
  <form method="dialog">
    <button value="cancel">Cancel</button>
    <button value="confirm">Delete</button>
  </form>
</dialog>

Paso 3: Manejar Escape, request-close y close

Escape o un gesto de la plataforma es una solicitud de cierre. requestClose() puede ejecutar la ruta de solicitud de cierre para que la aplicación pueda confirmarla o interceptarla. close() cierra directamente y puede establecer returnValue. Nunca interprete Escape como una eliminación confirmada.

Paso 4: Gestionar y restaurar el foco

Cuando se abre un modal, enfoque el mejor campo de entrada, botón de cancelar o encabezado; no coloque tabindex en el elemento dialog. Al cerrar, devuelva el foco al activador, o a un reemplazo estable si el activador fue eliminado.

Paso 5: Usar form method=dialog deliberadamente

method="dialog" cierra el diálogo y preserva el estado de los controles del formulario sin enviar una solicitud de red; el value del botón se convierte en returnValue. Si cancelar debe omitir la validación requerida, use formnovalidate o un close() explícito para que el usuario nunca quede atrapado.

Paso 6: Distinguir dialog de Popover

Un popover es no modal y reside en la capa superior (top layer). popover="auto" admite descarte ligero; manual permanece abierto hasta que se oculta explícitamente y permite múltiples popovers independientes. No utilice un popover donde se requiera la inercia modal.

Paso 7: Detectar soporte y proporcionar un fallback

Compruebe el soporte de HTMLDialogElement, showModal y closedby. Si no están disponibles, proporcione controles explícitos, manejo manual de Escape, gestión del foco y bloqueo del fondo. El fallback debe mantener el mismo contrato de cancelar y confirmar.

Paso 8: Probar el cierre y la accesibilidad

Pruebe Tab, Escape, clics exteriores, eventos táctiles, validaciones fallidas, aperturas repetidas, múltiples modales, gestos de retroceso y navegadores antiguos. Registre el motivo del cierre (confirmar, cancelar, escape, descarte ligero) y use un lector de pantalla para verificar el nombre accesible, el estado y el movimiento del foco.

Ejemplo de respuesta de alta calidad

“Una confirmación destructiva utiliza showModal() y closedby="closerequest"; el flujo más estricto utiliza none con un botón explícito de cancelar. La información de bajo riesgo puede usar any u popover="auto". method="dialog" devuelve el resultado, y cancelar puede omitir la validación cuando corresponda. Establezco el foco inicial, restauro el foco al activador, detecto soporte y aplico un fallback con controles explícitos y manejo manual de teclado/foco. Las pruebas cubren cada fuente de descarte y tecnología asistiva.”

Errores comunes

  • Usar any para cada diálogo → las acciones destructivas se cierran accidentalmente → mapee closedby al riesgo.
  • Agregar tabindex a dialog → la semántica de foco es incorrecta → enfoque un control interno o un encabezado.
  • Tratar close como requestClose → se omite la lógica de confirmación → distinga entre cierre solicitado y directo.
  • Hacer que el botón de cancelar de un formulario requerido falle la validación → el usuario queda atrapado → use formnovalidate o close.
  • Reemplazar un modal con un popover → el fondo permanece interactivo → use showModal cuando la inercia sea importante.
  • Probar únicamente con el mouse → los usuarios de teclado y pantallas táctiles no pueden salir → cubra Escape, Tab, clics exteriores y lectores de pantalla.

Preguntas de seguimiento y respuestas sólidas

Pregunta de seguimiento 1: ¿Cuál es la diferencia principal entre closerequest y none?

closerequest acepta Escape o una solicitud de cierre de la plataforma además de los controles del desarrollador; none solo acepta controles del desarrollador y se adapta a acciones irreversibles.

Pregunta de seguimiento 2: ¿Por qué showModal es más confiable que open?

Establece el estado modal, la inercia del fondo y el comportamiento de foco del navegador. Establecer únicamente open crea un diálogo no modal.

Pregunta de seguimiento 3: ¿Qué es returnValue después de Escape?

Escape no representa el valor de un botón de envío a menos que la aplicación establezca uno. Registre el motivo del cierre por separado como escape o solicitud de cierre (request-close).

Pregunta de seguimiento 4: ¿Cómo puede cancelar omitir la validación obligatoria?

Coloque formnovalidate en el control de cancelar o llame a close("cancel"); mantenga la validación normal en confirmar.

Pregunta de seguimiento 5: ¿Cuál es el fallback para navegadores antiguos?

Proporcione controles explícitos de abrir/cerrar y gestione manualmente Escape, el atrapamiento de foco (focus trap), el bloqueo de fondo y los motivos de cierre. Mantenga las pruebas de contrato idénticas cuando se restaure el soporte nativo.

Fuentes públicas

Preguntas relacionadas