Tengo un problema con el reventado de enfoque, tengo una ventana emergente con una barra de comandos que tiene 3 elementos de intervalo que usan íconos, y cuando paso a través de ellos funciona bien, hasta que paso al último elemento y tan pronto como aterrizar en él, me lleva de vuelta al primer elemento, y lo que esperaba que sucediera es que cuando me alejo del último elemento, debería volver al primer elemento. Haga clic en el ícono Guardar y use la pestaña llave
const element = document.getElementById("PromptsDialog"); const focusableElements = element.querySelectorAll("span:not([disabled])"); const firstFocusableElement = focusableElements[0]; const lastFocusableElement = focusableElements[focusableElements.length - 1]; element.addEventListener("keyup", function(e) { if (e.key === "Tab") { if (document.activeElement === lastFocusableElement) { firstFocusableElement.focus(); e.preventDefault(); } } }); <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="PromptsDialog" style="display: block;"> <div class="prompt-title-bar"> <h4 style="margin-top:-4px;">Options Prompt</h4> <div id="PromptsCommand" class=""> <div style="height:inherit"> <span type="" tabindex="1" data-toggle="tooltip" data-placement="top" title="" data-original-title="Save" class="" id="btnSaveWindow"><i class="fa fa-save"></i></span> <span type="" tabindex="2" data-toggle="tooltip" data-placement="top" title="" data-original-title="Remove Item" class="" id="btnRemoveFromItemsGrid"><i class="fa fa-trash"></i></span> <span type="" tabindex="3" data-toggle="tooltip" data-placement="top" title="" data-original-title="Close" class="" id="btnClosePromptDialog"><i class="fa fa-remove"></i></span> </div> </div> </div> </div>¿Alguna idea de por qué sucede cuando aterrizo en el último elemento?
¡Gracias!
Inmediatamente vuelve al primer elemento más o menos debido al momento de los eventos. En su código, está utilizando el evento ' keyup ', que se activa tan pronto como se suelta la tecla 'Tab'. Sin embargo, el último elemento se enfoca cuando se presiona la tecla 'Tab' (hacia abajo), por lo que presionar tabulador primero enfocará el último elemento, luego ejecutará su código cuando se suelte la pestaña, volviendo inmediatamente al primer elemento.
Una solución fácil es usar el evento ' keydown ' en su lugar.
const element = document.getElementById("PromptsDialog"); const focusableElements = element.querySelectorAll("span:not([disabled])"); const firstFocusableElement = focusableElements[0]; const lastFocusableElement = focusableElements[focusableElements.length - 1]; element.addEventListener("keydown", function(e) { if (e.key === "Tab") { if (document.activeElement === lastFocusableElement) { firstFocusableElement.focus(); e.preventDefault(); } } }); <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="PromptsDialog" style="display: block;"> <div class="prompt-title-bar"> <h4 style="margin-top:-4px;">Options Prompt</h4> <div id="PromptsCommand" class=""> <div style="height:inherit"> <span type="" tabindex="1" data-toggle="tooltip" data-placement="top" title="" data-original-title="Save" class="" id="btnSaveWindow"><i class="fa fa-save"></i></span> <span type="" tabindex="2" data-toggle="tooltip" data-placement="top" title="" data-original-title="Remove Item" class="" id="btnRemoveFromItemsGrid"><i class="fa fa-trash"></i></span> <span type="" tabindex="3" data-toggle="tooltip" data-placement="top" title="" data-original-title="Close" class="" id="btnClosePromptDialog"><i class="fa fa-remove"></i></span> </div> </div> </div> </div>Keydown es un mejor evento y esto también funciona con shift-tab
const element = document.getElementById("PromptsDialog"); const focusableElements = element.querySelectorAll("span:not([disabled])"); const lastIdx = focusableElements.length-1; focusableElements.forEach((elem, i) => { elem.dataset.next = i < lastIdx ? i+1 : 0; elem.dataset.prev = i >= 1 ? i-1 : lastIdx; }) element.addEventListener("keydown", function(e) { if (e.key === "Tab") { e.preventDefault(); const idx = +e.target.dataset[e.shiftKey ? "prev" : "next"]; focusableElements[idx].focus(); } }); <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="PromptsDialog" style="display: block;"> <div class="prompt-title-bar"> <h4 style="margin-top:-4px;">Options Prompt</h4> <div id="PromptsCommand" class=""> <div style="height:inherit"> <span type="" tabindex="1" data-toggle="tooltip" data-placement="top" title="" data-original-title="Save" class="" id="btnSaveWindow"><i class="fa fa-save"></i></span> <span type="" tabindex="2" data-toggle="tooltip" data-placement="top" title="" data-original-title="Remove Item" class="" id="btnRemoveFromItemsGrid"><i class="fa fa-trash"></i></span> <span type="" tabindex="3" data-toggle="tooltip" data-placement="top" title="" data-original-title="Close" class="" id="btnClosePromptDialog"><i class="fa fa-remove"></i></span> </div> </div> </div> </div>