Video Summary and Transcription
Esta charla discute los esfuerzos de accesibilidad en Discord, centrándose en la navegación por teclado y los desafíos enfrentados al implementar anillos de enfoque y contornos. El orador muestra un sistema unificado de anillos de enfoque y un control deslizante de saturación para abordar las preocupaciones de accesibilidad. También destacan la implementación de colores de roles y el uso de filtros CSS para mejoras de accesibilidad. La charla concluye con ideas sobre la verificación de accesibilidad en tiempo de ejecución y el desarrollo de un sistema central de tiempo de ejecución eficiente para verificar problemas de accesibilidad.
1. Introducción a la accesibilidad en Discord
Soy Brandon Dale, un ingeniero de software en Discord, y hablaré sobre la accesibilidad en Discord. Nuestro primer gran proyecto es la navegación por teclado, que garantiza que los usuarios puedan realizar todas las acciones con un teclado. Esto es crucial para la accesibilidad y también ayuda con la compatibilidad con lectores de pantalla. Permítanme demostrar la navegación por teclado de Discord. Primero, me enfocaré en la entrada de mensajes, luego usaré la tecla de tabulación para navegar a través de los elementos enfocables. También puedo navegar a través de los mensajes y usar atajos para acciones como responder. Uno de los desafíos que enfrentamos fue implementar anillos de enfoque, que resultaron tener muchos casos especiales. El uso de la propiedad CSS outline causó complicaciones, especialmente al tratar con contenedores con elementos enfocables y desbordamiento oculto.
Estoy aquí para hablar sobre la accesibilidad en Discord. Esta será una charla amplia centrada en la ingeniería donde hablaré sobre algunos de los problemas más interesantes en los que hemos trabajado, los espacios problemáticos en torno a ellos y luego analizaré los detalles técnicos de las soluciones que hemos construido. Ahora, antes de hacer eso, quiero agradecer al resto de mi equipo porque estoy definitivamente aquí en nombre de muchas personas realmente geniales que han hecho gran parte del trabajo del que voy a presumir. Así que solo algunas presentaciones rápidas. Nuestro equipo incluye a Evelyn, nuestra gerente de ingeniería, John es otro ingeniero, Saan es un diseñador, Nick nos ayuda con el marketing, Meghan es otra ingeniera y, por supuesto, yo mismo, otro ingeniero.
Ahora, el primer gran proyecto del que quiero hablar es la navegación por teclado. Esto fue algo que hicimos el año pasado y fue un proyecto con un objetivo muy amplio de asegurarnos de que puedas hacer todo lo que necesitas hacer en Discord solo con un teclado. Esta es una característica de accesibilidad realmente importante porque hay muchas personas que no pueden o tienen dificultades para usar un mouse. Y también descubrimos que un buen soporte de teclado es un buen indicador de cómo podría funcionar un lector de pantalla en ciertos casos, ya que ambos se basan en la navegación de un cursor entre elementos enfocables. Así que obtuvimos muchos beneficios en ambos casos.
Permítanme demostrar cómo se ve la navegación por teclado en Discord, en caso de que no estén familiarizados con Discord y no hayan utilizado la navegación por teclado. Aquí lo tengo en funcionamiento y solo quiero llamar su atención aquí abajo, porque ahí es donde voy a empezar. Así que voy a enfocar esta entrada de mensajes, presionar tabulación, y ahora verán este anillo de enfoque azul alrededor de la entrada de mensajes. Si presiono tabulación nuevamente, puedo moverme a través de otros elementos enfocables, shift + tabulación para retroceder. Vamos a un canal que tiene algunos mensajes. Vamos a hacer React Internals. Verán que mi anillo de enfoque persiste porque usé el teclado para llegar a este canal. Y si presiono la flecha hacia arriba, puedo moverme hacia arriba a través de los mensajes, la flecha hacia abajo me lleva hacia abajo. Puedo usar atajos de teclado mientras estoy enfocado en los mensajes, como R para responder, y luego puedo usar una navegación similar con las teclas de flecha en todas las demás listas que pueden ver aquí. Antes de hablar sobre el proyecto, quiero mencionar esta publicación de blog de John. Él hizo gran parte del trabajo del que voy a hablar y escribió esta publicación de blog realmente excelente sobre el tema. Así que si quieres leer una versión más extensa de esto, te recomiendo que lo revises. Tiene muchos detalles realmente interesantes.
Ahora, la primera parte importante de la navegación por teclado de la que quiero hablar son los anillos de enfoque, porque son engañosamente simples. Parece algo que debería ser relativamente fácil, pero encontramos que hay muchos casos especiales que lo hacen realmente complicado si quieres escalarlo. Tradicionalmente, esto es algo que se implementaría con la propiedad CSS outline. Y esto es algo que intentamos hacer, pero encontramos que había muchas complicaciones que quiero explicar rápidamente. Así que hubo algunos problemas con el uso de outline que encontramos bastante rápido. El primero fue que al usar overflow hidden en un contenedor que puede tener elementos enfocables
2. Desafíos con Anillos de Enfoque y Contornos
Si me desplazo a este botón, verás el anillo de enfoque en todos los lados excepto en el más a la izquierda, debido a que está fuera del área de desbordamiento. Los navegadores recortan este anillo de enfoque, lo cual se puede solucionar teniendo cuidado con los márgenes y rellenos. La propiedad outline solo se puede aplicar al elemento objetivo, no a su contenedor. CSS carece de una buena solución para esto, ya que la pseudo clase focus-within aplica el estilo a cualquier descendiente. Además, la propiedad outline no se adapta a diferentes colores de fondo. Una solución futura en la que se está trabajando es la función de contraste de color en la especificación de nivel cinco del módulo de color de CSS. La propiedad outline-offset solo permite una aplicación uniforme, a diferencia de los márgenes y rellenos.
Corríamos el riesgo de recortar el contorno. Así que te lo mostraré aquí. Si me desplazo a este botón, verás que puedes ver el anillo de enfoque en todos los lados excepto en el más a la izquierda. Y eso se debe a que está justo fuera de esa área de desbordamiento. Y tal como está, los navegadores recortarán ese anillo de enfoque. Esto es algo que generalmente se puede solucionar teniendo más cuidado con los márgenes y rellenos. Pero estábamos usando desbordamiento por algunas otras razones, así que fue un poco complicado. Y también queríamos evitar la posible batalla cuesta arriba de tener que arreglar siempre, ya sabes, el uso de desbordamiento oculto para evitar esto. Lo siguiente con lo que nos encontramos es que el contorno solo se puede aplicar al elemento objetivo. Entonces, al elemento que se está enfocando. Así que, si miras a la derecha aquí, tenemos una entrada de chat que se parece mucho a lo que tenemos en Discord, donde tenemos una entrada y luego un botón, y todos están en este contenedor lógico. E idealmente, lo que queremos es, cuando me enfoco en esta entrada, no queremos que se aplique ese anillo de enfoque al elemento de entrada real. Queremos que se aplique en ese contenedor con el borde negro. Y si miras Discord, esto es lo que hacemos. Pero con CSS y la propiedad outline, no hay una buena manera de hacerlo ahora mismo. Hay esta pseudo clase focus-within que te permite aplicar un estilo si algún descendiente está enfocado. Y si lo habilitamos y hacemos clic aquí, verás que nos da lo que queremos, pero la advertencia es que se aplica si algún descendiente está enfocado. Entonces, si presiono tabulación para salir de la entrada, verás que el botón está enfocado, y ese anillo de enfoque en el contenedor permanece. Entonces, esta propiedad simplemente no es lo suficientemente granular para nosotros.
Otra cosa es que esta propiedad outline no puede adaptarse automáticamente a diferentes colores de fondo. Así que verás aquí que tenemos un botón, y esto es generalmente lo que tenemos, es un botón a nivel del sistema de diseño que se utiliza en muchos contextos diferentes. Y si me desplazo al primero, ese anillo de enfoque azul se ve bastante bien. Pero en el siguiente con este fondo borroso, no tanto. Ya sabes, es difícil de ver. Y queríamos una solución donde los diseñadores e ingenieros no tuvieran que pensar y aplicar manualmente diferentes anillos de enfoque según el contexto. Y con outline, eso simplemente no es posible actualmente. Ahora, hay algo en lo que se está trabajando llamado la función de contraste de color en la especificación de nivel cinco del módulo de color de CSS, pero aún es un trabajo en progreso y aún no tiene soporte en los navegadores. Pero estamos deseando mucho que esto suceda, porque esto ayudará a resolver muchos de estos problemas de adaptación de color del anillo de enfoque. Y luego esto es algo más pequeño y molesto, la propiedad outline-offset, que es lo que se puede usar para desplazar el contorno del elemento objetivo hacia afuera o hacia adentro. Solo puede tomar un valor único, por lo que solo se puede aplicar de manera uniforme. Entonces, a diferencia de los márgenes, rellenos y bordes redondeados, no te permite aplicar un contorno que sea
3. Evolución del manejo de bordes redondeados en los navegadores
Tuvimos casos en los que queríamos un desplazamiento más asimétrico. Sin embargo, los navegadores ahora han solucionado el problema de los contornos rectangulares alrededor de los botones circulares. Esto muestra cómo trabajamos con las limitaciones de la plataforma mientras esperamos el soporte nativo del navegador en el futuro.
diferentes en cualquiera de los lados. Y tuvimos algunos casos en los que queríamos un desplazamiento más asimétrico. Ahora, este último aquí, el contorno no respeta el radio del borde, esto ha sido cierto durante mucho tiempo, pero si me desplazo a este botón aquí, que tiene un borde redondeado, verás que en realidad respeta el radio del borde. Y eso se debe a que esto fue solucionado. Cuando escribimos nuestra solución, cuando estábamos trabajando en esto, ese no era el caso. Sabes, los navegadores todavía mostraban siempre este contorno rectangular alrededor de los botones circulares, pero cuando estaba escribiendo esta charla, lo probé y he aquí, los navegadores han resuelto este problema. Así que creo que este es un gran ejemplo de cómo realmente estamos tratando de trabajar con muchas de las limitaciones de la plataforma, pero la plataforma también sigue evolucionando. Y espero que algún día algunas de las soluciones que hemos construido aquí sean manejadas de forma nativa por el navegador.
4. Sistema de Anillo de Enfoque Unificado y Control Deslizante de Saturación
Creamos un sistema de anillo de enfoque unificado que es fácil de usar y nos ha funcionado bien. Puedes aplicar el anillo de enfoque alrededor de un elemento interactivo o enfocable utilizando la API de anillo de enfoque. El alcance del anillo de enfoque sirve como punto de referencia para la posición. Para usar el anillo de enfoque, envuélvelo alrededor del elemento deseado y configúralo con propiedades como offset, within, ring target y focus target. Otro proyecto en el que trabajamos es el control deslizante de saturación, que permite a los usuarios desaturar los colores en la aplicación de escritorio. Esta opción se agregó para abordar problemas de accesibilidad. Al ajustar el control deslizante de saturación, los usuarios pueden ver los efectos en la interfaz de usuario, incluyendo botones, enlaces y opciones de color personalizadas.
Entonces, esos son los problemas con los que nos encontramos. Ahora esta es la solución que construimos. Así que creamos un sistema de anillo de enfoque unificado y puedes ver aquí que también lo hemos compartido como código abierto. Entonces, si estás interesado en usar esto, es muy fácil de usar y nos ha funcionado muy bien. Así que permíteme mostrarte cómo se ve realmente adoptar esto. Aquí está el ejemplo de aplicación del repositorio de anillos de enfoque. Verás que hay dos importaciones principales, anillo de enfoque y alcance de anillo de enfoque. El anillo de enfoque es la API principal y es lo que usarás para renderizar el anillo de enfoque alrededor de un elemento interactivo o enfocable. Y luego, el alcance de anillo de enfoque es una especie de punto de referencia para el anillo de enfoque. Así que si lo vemos aquí, todo lo que tienes que hacer con el alcance de anillo de enfoque es proporcionar una referencia de contenedor que apunte a un elemento DOM y eso se utilizará como punto de referencia para cosas como la posición para asegurarse de que cosas como la ocultación al desplazarse funcionen como se espera. Así que querrás colocar uno de estos en la raíz de tu aplicación, así como cada vez que crees un contenedor desplazable o un contenedor de posición absoluta. Ahora, en cuanto al anillo de enfoque, es muy fácil de usar. Todo lo que tienes que hacer es encontrar el elemento interactivo enfocable al que deseas aplicar el anillo y luego envolverlo. Puedes agregar algunas propiedades adicionales para configurarlo, como una propiedad de desplazamiento, que funcionará con un número singular, al igual que el desplazamiento del contorno, o puedes proporcionarle un objeto como arriba cuatro, izquierda tres, etc. También puedes usar el valor within para tratarlo como un enfoque dentro. Entonces, el anillo se renderizará cada vez que se enfoque cualquier descendiente. Y luego hay propiedades como ring target y focus target, que ambas toman referencias y te permiten configurar en qué elemento se aplica el anillo de enfoque y en qué elemento estamos escuchando eventos de enfoque. Eso nos da ese comportamiento del que hablaba antes de apuntar a un elemento diferente al que está enfocado, como en nuestro ejemplo de entrada de chat. El siguiente proyecto del que quiero hablar es el control deslizante de saturación, que fue un proyecto relativamente reciente en el que agregamos la opción de desaturar los colores en la aplicación de escritorio. Esto se agregó porque después de nuestro cambio de imagen, algunos usuarios de accesibilidad se quejaron de que la alta saturación les resultaba un poco difícil. Queríamos asegurarnos de que hubiera una opción para garantizar que su experiencia en Discord siguiera siendo cómoda. Permíteme mostrarte cómo puedes usar el control deslizante de saturación y cómo afecta a la interfaz de usuario. Entonces, si entro en Discord, abro mis configuraciones y voy a accesibilidad, verás el control deslizante aquí en la parte superior configurado actualmente al 100 por ciento y puedes arrastrarlo hasta cero. Y hay una interfaz de usuario de ejemplo debajo de él que puedes usar para ver cómo los cambios de saturación afectan las cosas. Entonces, si lo bajo, digamos, al 50 por ciento, verás que los botones y el enlace y todas esas otras cosas, el control deslizante se han vuelto un poco menos saturados. E incluso puedo bajarlo completamente a cero para darte una experiencia en escala de grises. Así que lo subiré, digamos, al 100. Luego tenemos esta opción a continuación, aplicar a opciones de color personalizadas, donde también puedes aplicarlo a cosas como los colores de roles, que son colores definidos por el usuario. Cuando creas un rol, puedes elegir tu propio color. Entonces, verás aquí donde dice Ultron, es este bonito rosa brillante.
5. Colores de Roles y Saturación
Y si arrastro esto hacia abajo con eso habilitado, también se desatura. Pero si desactivo esto, permanece ese color brillante. La parte interesante sobre el problema de los colores de roles es que estos colores son definidos por el usuario. Simplemente cambiar la saturación no garantiza que se vea bien. Podrías estar introduciendo algunos problemas de contraste realmente difíciles. Permíteme mostrarte cómo implementamos eso. Inicialmente, nuestros colores se implementaron como valores hexadecimales simples. Los tradujimos al formato HSL y aplicamos un poco de matemáticas. Para los colores definidos por el usuario, las cosas se complican debido a los requisitos de contraste. También ajustamos un valor de brillo, haciendo cosas diferentes entre el modo oscuro y el modo claro. En el modo oscuro, a medida que la saturación se acerca a cero, aumentamos el brillo en un 50%. En el modo claro, dividimos la saturación a 0.5. Esto nos da el comportamiento de un texto más claro en modo oscuro y un texto más oscuro en modo claro.
Y si arrastro esto hacia abajo con eso habilitado, también se desatura. Pero si desactivo esto, permanece ese color brillante. Ahora, la parte interesante sobre el problema de los colores de roles es que estos colores son definidos por el usuario. Y simplemente cambiar la saturación no garantiza que se vea bien. Podrías estar introduciendo algunos problemas de contraste realmente difíciles. Así que notarás aquí que a medida que lo bajo, asegurémonos de que esté activado. Sí. Vuelve a encenderlo. A medida que ajusto la saturación hacia abajo, los colores de estos roles en la derecha tienden a normalizarse hacia este color gris oscuro o negro. Pero si voy al tema oscuro, verás que todos se han normalizado hacia este color más blanco. Así que hemos aplicado un nivel adicional de lógica para asegurarnos de que sigan siendo legibles. Permíteme mostrarte cómo implementamos eso. Inicialmente, nuestros colores se implementaron simplemente como valores hexadecimales simples. Entonces, lo que hicimos fue traducirlos al formato HSL. Si no estás familiarizado, eso significa tono saturación luminosidad y te permite definir un color en esos términos. Ahora, en lugar de simplemente usar el valor de saturación predeterminado, aplicamos un poco de matemáticas. Entonces, lo que hacemos es multiplicarlo por esta variable CSS de saturación. Ahora, este será un valor entre 0 y 1, y es lo que se controla con ese control deslizante de saturación. Entonces, cuando el control deslizante está al 50%, esto será 0.5 y multiplicará ese valor por eso. Entonces, al 0%, esto terminará siendo cero dándonos un valor de escala de grises, y al 100%, será uno, dándonos el color original. Así que esa es toda la lógica que se requiere para aplicar la saturación a nuestros propios colores. Ahora, para los colores definidos por el usuario, las cosas se complican debido a los requisitos de contraste. Entonces, lo que hacemos es ajustar también un valor de brillo, y hacemos cosas diferentes entre el modo oscuro y el modo claro. En el modo oscuro, a medida que la saturación se acerca a cero, nos acercamos a 1.5 para el brillo. Entonces, aumentamos el brillo en un 50%. Ahora, en el modo claro, hacemos lo contrario. A medida que la saturación se acerca a cero, la dividimos a 0.5, es decir, un 50%. Entonces, lo que esto nos da es el comportamiento donde, en el modo oscuro, las cosas se vuelven más claras. Y en el modo claro, las cosas se vuelven más oscuras. Y eso nos da el
6. Mejoras de Accesibilidad y Verificación en Tiempo de Ejecución
Para mejorar la accesibilidad, utilizamos la propiedad CSS filter para la desaturación, ajustes de contraste y ajustes de brillo. Agregamos soporte para teclado y lectores de pantalla en las interacciones de arrastrar y soltar. Nuestro sistema de arrastrar y soltar, construido sobre React D&D, ahora cuenta con una biblioteca de código abierto llamada React D&D Accessible Backend para el soporte de teclado y lectores de pantalla. También estamos trabajando en la verificación de accesibilidad en tiempo de ejecución para encontrar y reportar automáticamente problemas a los desarrolladores sin interrumpir su flujo de trabajo.
El comportamiento de texto más claro en modo oscuro y texto más oscuro en modo claro. Y para lograr eso, utilizamos la propiedad CSS filter, donde primero aplicamos la desaturación. Luego también aplicamos algunos ajustes de contraste con el mismo valor de saturación. Y luego, finalmente, hacemos los ajustes de brillo, lo que nos da ese color oscuro o brillante final. Lo siguiente de lo que quiero hablar es del arrastrar y soltar accesible. Arrastrar y soltar es un patrón de interacción bastante común en Discord donde puedes reordenar diferentes elementos. Y hasta hace muy poco, solo podías hacerlo con el mouse. Pero este último trimestre, lanzamos una actualización que agrega soporte tanto para teclado como para lectores de pantalla para hacer lo mismo. Permíteme mostrarte cómo se ve. Así que si vuelvo a Discord y uso mi teclado para navegar hasta mi lista de servidores en la parte izquierda, puedo presionar Comando + D en una Mac, y ahora puedo usar las flechas hacia arriba y hacia abajo para moverme. Así que voy a poner esto debajo aquí. Presiono Enter y desaparece. También puedo hacer eso con mis canales. Permíteme ir a ellos. Así que si presiono Comando + D, voy a poner General en la parte superior y debería funcionar. Así que esto debería ser cierto automáticamente para cualquier superficie de arrastrar y soltar en Discord. Nuestro sistema de arrastrar y soltar se basa en React D&D, que ha sido una herramienta de trabajo para arrastrar y soltar en la comunidad de React durante mucho tiempo, pero en los últimos años ha perdido un poco de accesibilidad y desarrollo de funciones. Exploramos la migración a una solución más moderna como React Beautiful D&D, pero nos encontramos con algunos problemas debido a la complejidad de nuestra implementación actual. Intentamos encontrar algunas opciones de código abierto que nos permitieran obtener lo que queremos con React D&D, pero simplemente no pudimos encontrarlas, así que seguimos adelante y lo construimos. Esta es una biblioteca que acabamos de publicar de forma reciente llamada React D&D Accessible Backend. Esto fue escrito por John, e implementa el soporte de teclado y lectores de pantalla para React D&D. Si no estás familiarizado con React D&D, utiliza el concepto de un backend para encapsular y manejar los diferentes eventos nativos, por lo que esto es algo que puedes usar junto con otros backends más establecidos para obtener soporte de teclado y lectores de pantalla de manera sencilla. Puedes encontrarlo en ese enlace, así que échale un vistazo si actualmente estás utilizando React D&D y quieres mejorar tu accesibilidad. Muy bien. Entonces, el último proyecto importante del que quiero hablar es uno experimental, y eso es la verificación de accesibilidad en tiempo de ejecución. Esto es algo en lo que estamos trabajando y explorando actualmente, y tenemos mucha emoción al respecto, así que solo quiero mostrarte cómo podría ser para nosotros y luego hablar sobre la implementación técnica del sistema central en tiempo de ejecución. Ahora, aquí tienes un ejemplo de una versión muy temprana en la que hemos estado trabajando, solo para darte una idea de lo que estoy hablando. Ten en cuenta que esto es completamente interno, solo para desarrolladores. Esto no es algo que un usuario de Discord verá nunca, pero te da una idea de lo que estamos hablando con las verificaciones de accesibilidad en tiempo de ejecución. Queremos poder encontrar y reportar automáticamente problemas de accesibilidad a los desarrolladores mientras trabajan en el producto. Hay sistemas existentes de verificación automática de accesibilidad, pero casi todos requieren que detengas lo que estás haciendo, abras alguna herramienta de desarrollo, lo ejecutes y luego esperes los resultados, y queríamos eliminar eso.
7. Sistema Central en Tiempo de Ejecución y Mutation Observer
Estamos trabajando en un sistema central en tiempo de ejecución eficiente para verificar problemas de accesibilidad. Desactivamos el sistema si la API Navigator.scheduling.isInputPending no está disponible, lo cual nos indica si un usuario está interactuando con la interfaz. Seguimos el estado a nivel de módulo y tenemos una función para restablecer el estado. Nuestro punto de partida es un observador de mutaciones que busca mutaciones interesantes en el documento raíz y ejecuta nuestra verificación. Restablecemos nuestro estado cada vez que ocurre una mutación para garantizar la validez de nuestras comprobaciones.
En ese punto de fricción. Ahora, el desafío aquí es que queremos que esto se ejecute prácticamente sin obstáculos, por lo que debemos asegurarnos de no hacer nada demasiado intensivo y de no perder cuadros ni nada por el estilo, lo cual es realmente difícil porque tenemos que realizar muchos cálculos diferentes para verificar problemas de accesibilidad. Así que quiero hablar sobre el sistema central en tiempo de ejecución en el que estamos trabajando y la idea detrás de cómo podemos hacerlo eficiente. Aquí tienes una vista simplificada del código en el que estamos trabajando ahora para el sistema central en tiempo de ejecución. Lo primero que hay que tener en cuenta es que normalmente habría una gran lista de reglas de accesibilidad, que definen la lógica y el comportamiento para consultar los nodos DOM relevantes y cómo verificar las relaciones que queremos validar, pero esa es mucha complejidad en la que no estamos realmente interesados aquí, así que las he excluido por ahora. Lo primero que hay que tener en cuenta es que esto debería ejecutarse constantemente. Ahora, lo que hacemos es desactivar todo este sistema si esta API específica no está disponible. Navigator.scheduling.isInputPending. Probablemente no estés familiarizado con esta porque solo está implementada en Chromium. Si quieres leer al respecto, te recomiendo encarecidamente esta URL, web.dev.isInputPending. Es un artículo realmente bueno de Google, que está trabajando en ello, que explica qué es y por qué queremos incorporarlo a la plataforma. En un sentido simple, lo que hace es indicarnos si un usuario está interactuando actualmente con la interfaz. Entonces, ¿han hecho clic en un botón? ¿Están escribiendo? ¿Están pasando el cursor sobre algo? Y lo que hacemos es utilizar esto para salir de nuestro sistema central porque lo que estamos haciendo no es realmente el trabajo más importante. Queremos que la aplicación siga siendo receptiva. Así que esto nos da una forma de hacerlo, y lo desactivamos si no existe porque no importa realmente. Esta es una herramienta orientada a los desarrolladores, y la mayoría de nuestros desarrolladores al menos van a comprobar cómo funcionan las cosas en Chrome en algún momento. Después de eso, tenemos un estado a nivel de módulo donde seguimos cosas, como los ID de tiempo de espera, y luego qué regla estamos comprobando actualmente, qué nodo para esa regla estamos mirando, el conjunto actual de nodos y luego la comprobación real que estamos intentando construir. Ahora, todo esto es a nivel de módulo porque es efectivamente un estado global. Solo queremos una instancia de esta cosa en ejecución. Luego tenemos una función aquí para restablecer ese estado a los valores iniciales.
Ahora, aquí está el punto de partida más interesante, nuestra función de registro. Verás que no hacemos nada si nuestra constante should run check no es verdadera. Luego, nuestro punto de partida es con un observador de mutaciones. Lo que queremos hacer es buscar mutaciones, todas las mutaciones interesantes, en el documento raíz y ejecutar nuestra comprobación cuando eso ocurra. Ahora, esto es algo que ocurre con mucha frecuencia. Cualquier actualización del DOM desde la raíz va a desencadenar esto. Así que tenemos que tener más lógica más adelante para asegurarnos de que esto no ocurra demasiado o no se active con demasiada frecuencia. Pero verás que escuchamos todos los cambios de atributos, lista de hijos y subárbol. Ahora, lo primero que hacemos en este callback de mutación es restablecer nuestro estado. Y eso es porque cada vez que llega una mutación, no podemos estar seguros de que no haya invalidado las comprobaciones que ya hemos realizado. No sabemos si es un cambio de atributo o un cambio de subárbol que puede haber corregido o agregado
8. Lógica de Debounce y Programación
Para manejar el comportamiento de debounce, comenzamos desde cero y realizamos una verificación de tiempo de espera. La función de verificación de programación se realiza con un tiempo de espera de aproximadamente 250 milisegundos y se llama utilizando la devolución de llamada de solicitud de tiempo de inactividad. Esto asegura que la verificación se ejecute solo cuando el DOM está en un estado tranquilo con tiempo de inactividad disponible.
Para manejar el comportamiento de debounce, comenzamos desde cero y realizamos una verificación de tiempo de espera. Luego hacemos una verificación de tiempo de espera, lo que nos brinda un comportamiento de debounce. Por último, simplemente hacemos una verificación de programación con un tiempo de espera de aproximadamente 250 milisegundos. En esta función de verificación de programación, simplemente llamamos a la devolución de llamada de solicitud de tiempo de inactividad. Así que tenemos un debounce. Y luego, después de que se ejecute el debounce, lo programamos para el próximo período de inactividad. Esto nos brinda una experiencia realmente buena donde probablemente no ejecutaremos esto hasta que el DOM esté en un estado tranquilo y haya algún tiempo de inactividad que podamos utilizar. Lo siguiente es ejecutar comprobaciones de accesibilidad. Y esta es la lógica principal. Verificamos la regla. Rellenamos los nodos del DOM para esa regla, si aún no lo hemos hecho. Si no hay nodos del DOM relevantes, pasamos a la siguiente regla. Luego, hacemos un poco de lógica de programación inteligente. Esto se toma de la publicación del blog sobre isInputPending. Efectivamente, lo que hacemos es tomar una marca de tiempo actual. Establecemos un plazo de 16 milisegundos. Y luego recorremos los nodos. Y si hay una entrada pendiente, si hemos visto que el usuario está intentando interactuar o si hemos alcanzado nuestro plazo, salimos de este bucle. Luego, después de esto, tenemos una lógica para reprogramar la siguiente verificación. Y aquí tenemos la lógica real para ejecutar la verificación. Y hacemos un poco de hashing para asegurarnos de no informar el mismo problema demasiadas veces. Puedes imaginar que puedes tener una lista que tenga cientos del mismo elemento. No queremos informar eso como 100 problemas diferentes. Podemos identificar que probablemente sean la misma instancia del mismo tipo de elemento. Luego, después de eso, es donde verificamos si hay otro nodo que debamos verificar para esta regla. Y si lo hay, programamos uno nuevo. De lo contrario, pasamos a la siguiente regla. Y eso es básicamente todo. Todas esas API juntas nos brindan un sistema de tiempo de ejecución realmente flexible y eficiente para ejecutar estas comprobaciones potencialmente costosas. Ahora, esto es algo que eventualmente queremos abrir al código fuente, pero también es algo que actualmente está en progreso. Así que definitivamente estén atentos para más información al respecto. Muy bien. Esos son todos los proyectos realmente geniales de los que quería hablar. Aprecio mucho que todos estén escuchando. Lo último que quería mencionar es que si tienen algún comentario sobre accesibilidad, tal vez usen algunas de nuestras funciones de accesibilidad, tenemos un formulario de comentarios sobre accesibilidad en esta URL, dis.gd/A11y. Nos encantaría escuchar sus comentarios para asegurarnos de construir el producto más accesible posible. Gracias de nuevo.
Comments