Estoy tratando de resolver un problema de tabulación dentro de mi modal cuando está presente un <iframe> de origen cruzado.
Lo que estoy notando:
.focus() con javascript..focus() con javascript para mantener la accesibilidad del teclado. .focus() está restringido en este uso. Y como no puedo establecer el enfoque, la trampa de tabulación del teclado modal está rota.
¿Alguien ha tenido éxito en esta área?
Ejemplos HTML :
Funciona (no necesito establecer el foco con javascript en el iframe)
<input type="text" /> <iframe /> <input type="text" />Si iframe es el primer o último elemento enfocable, tendré que usar javascript para establecer el enfoque para mantener la trampa del teclado modal
<input type="text" /> <iframe />o
<iframe /> <input type="text" />JavaScript :
var KEY = { TAB: 9, }, allowedFocusableElements = 'a[href], area[href], input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]'; function openDialog(e) { // Get focusable elements. dialogFocusableElements = dialog.querySelectorAll(allowedFocusableElements); dialogFirstElement = dialogFocusableElements[0]; dialogLastElement = dialogFocusableElements[dialogFocusableElements.length - 1]; document.addEventListener("keydown", processKeys); } function processKeys(event) { if (event.keyCode === KEY.TAB && !event.shiftKey) { if (document.activeElement === dialogLastElement) { event.preventDefault(); dialogFirstElement.focus(); } } else if (event.keyCode === KEY.TAB && event.shiftKey) { if (document.activeElement === dialogFirstElement) { event.preventDefault(); dialogLastElement.focus(); } } }Todo esto se redujo a tratar de usar .focus() en un iFrame de origen cruzado. Dado que no parece haber ninguna forma de evitar esto (considerando el control del orden de las pestañas y el enfoque con javascript), he implementado (no tan idealmente) algunos elementos de pestañas adicionales antes o después del iFrame dependiendo de dónde se encuentre en el modal.
Si el iFrame es el primer elemento enfocable, colocamos un elemento "pseudo" tabulado antes de él y, de la misma manera, si es el último elemento enfocable, colocamos un elemento tabulado después.
Aquí está ese fragmento de código en particular:
var KEY = { TAB: 9, }, allowedFocusableElements = 'a[href], area[href], input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]'; function openDialog(e) { // Get focusable elements. dialogFocusableElements = dialog.querySelectorAll(allowedFocusableElements); dialogFirstElement = dialogFocusableElements[0]; dialogLastElement = dialogFocusableElements[dialogFocusableElements.length - 1]; // Tab helpers for iFrames. if (dialogFirstElement.tagName && dialogFirstElement.tagName === "IFRAME") { iframeTabHelper = document.createElement("div"); iframeTabHelper.setAttribute("tabindex", "0"); iframeTabHelper.classList.add("iframe-helper-button"); dialogFirstElement.parentNode.insertBefore(iframeTabHelper, dialogFirstElement); // Re-get focusable elements. dialogFocusableElements = dialog.querySelectorAll( allowedFocusableElements ); dialogFirstElement = dialogFocusableElements[0]; } if (dialogLastElement.tagName && dialogLastElement.tagName === "IFRAME") { iframeTabHelper = document.createElement("div"); iframeTabHelper.setAttribute("tabindex", "0"); iframeTabHelper.classList.add("iframe-helper-button"); dialogLastElement.parentNode.insertBefore(iframeTabHelper, dialogLastElement.nextSibling); // Re-get focusable elements. dialogFocusableElements = dialog.querySelectorAll( allowedFocusableElements ); dialogLastElement = dialogFocusableElements[dialogFocusableElements.length - 1]; } document.addEventListener("keydown", processKeys); } function processKeys(event) { if (event.keyCode === KEY.TAB && !event.shiftKey) { if (document.activeElement === dialogLastElement) { event.preventDefault(); dialogFirstElement.focus(); } } else if (event.keyCode === KEY.TAB && event.shiftKey) { if (document.activeElement === dialogFirstElement) { event.preventDefault(); dialogLastElement.focus(); } } }No es perfecto, pero mantiene el funcionamiento de las pestañas y la trampa del teclado.
Probablemente podría agregar algunas comprobaciones para verificar si el iFrame es de origen cruzado, o incluso mejor, reescribir para verificar si hay algún elemento que restrinja la aplicación .focus() , no solo iFrames.