cuando presiono las teclas arriba y abajo, quiero que cambie el elemento "div" seleccionado. Cómo puedo conseguir esto. presionando la tecla hacia abajo en el teclado, la selección debe ir a una línea inferior.
document.addEventListener("DOMContentLoaded", function(event) { // <-- add this wrapper var element = document.querySelectorAll('.element'); if (element) { element.forEach(function(el, key){ el.addEventListener('click', function () { console.log(key); el.classList.toggle("active"); element.forEach(function(ell, els){ if(key !== els) { ell.classList.remove('active'); } console.log(els); }); }); }); } }); .element{ background: gray; width:200px; padding:10px; margin-bottom:1px; } .element.active{ background: red; } <section> <div class="element">BOX</div> <div class="element">BOX</div> <div class="element">BOX</div> <div class="element">BOX</div> <div class="element">BOX</div> <div class="element">BOX</div> </section>Pase la longitud de la matriz a la función de escucha. Si tiene esa función que devuelve una nueva función (un cierre), puede tomar nota del índice del elemento actual y compararlo con 0 o con la longitud de la matriz. Y debido a que mantiene un registro del índice actual, no necesita recorrer todos los elementos para eliminar la clase activa, simplemente elimine la clase del elemento en el que se encuentra y agréguela al siguiente.
// Grab all the elements var elements = document.querySelectorAll('.element'); // Call a function as a key press handler that returns // a new function (the actual listener) // that deals with the key presses. We do this // because we want to keep a variable `index` to identify which // element in the collection we're on, and a closure // (a function that hangs on to its local lexical environment // when it's returned) is very convenient document.addEventListener('keydown', handler(elements.length - 1), false); // Set the initial element elements[0].classList.add('active'); // So this is the handler that returns the closure. // We pass in the array length, set up the index variable, // and return a new listener function that deals with the key presses function handler(arrayLength) { let index = 0; return function(e) { if (e.code === 'ArrowUp' && index > 0) { elements[index].classList.remove('active'); --index; elements[index].classList.add('active'); } if (e.code === 'ArrowDown' && index < arrayLength) { elements[index].classList.remove('active'); ++index; elements[index].classList.add('active'); } } }; .element { background: gray; width: 200px; padding: 10px; margin-bottom: 1px; } .active { background: red; } <section> <div class="element">BOX</div> <div class="element">BOX</div> <div class="element">BOX</div> <div class="element">BOX</div> <div class="element">BOX</div> <div class="element">BOX</div> </section>Documentación adicional
¿Te refieres a algo como esto?
document.addEventListener("DOMContentLoaded", function(event) { // <-- add this wrapper var element = document.querySelectorAll('.element'); if (element) { element.forEach(function(el, key){ el.addEventListener('click', function () { el.classList.toggle("active"); element.forEach(function(ell, els){ if(key !== els) { ell.classList.remove('active'); } }); }); }); document.body.onkeydown = function(event) { if(event.key=="ArrowUp" && document.getElementsByClassName("active").length > 0) { event.preventDefault(); var active = document.getElementsByClassName("active")[0]; if(active.previousElementSibling) active.previousElementSibling.classList.add("active"); active.classList.remove("active"); return false; }; if(event.key=="ArrowDown" && document.getElementsByClassName("active").length > 0) { event.preventDefault(); var active = document.getElementsByClassName("active")[0]; if(active.nextElementSibling) active.nextElementSibling.classList.add("active"); active.classList.remove("active"); return false; } else if(event.key=="ArrowDown") { event.preventDefault(); element[0].classList.add("active"); //If nothing is selected, use element[element.legth − 1] for the last element] return false; }; }; }; }); .element{ background: gray; width:200px; padding:10px; margin-bottom:1px; } .element.active{ background: red; } <section> <div class="element">BOX</div> <div class="element">BOX</div> <div class="element">BOX</div> <div class="element">BOX</div> <div class="element">BOX</div> <div class="element">BOX</div> </section>Para seleccionar el elemento, sugeriría usar una sola función ( setSelected en el ejemplo), luego puede configurar más fácilmente el elemento activo, ya sea con un clic, una pulsación de tecla u otra llamada. Además de eso, no distribuyes la lógica en varios lugares, en caso de que quieras que suceda algo extra cuando un elemento se vuelve activo.
document.addEventListener("DOMContentLoaded", function(event) { // <-- add this wrapper const elements = document.querySelectorAll('.element'); if (elements) { let selected = -1; function setSelected(index){ //single entry point for selecting an element if(selected===index)return; const activeClass = 'active'; if(selected >=0)elements[selected].classList.remove(activeClass); elements[selected = index].classList.add(activeClass); } elements.forEach((el, index) => el.onclick = e=>setSelected(index)); document.body.onkeydown = e=>{ if(selected < 0)return; //no element selected yet let i = selected; const key = e.key; if(key==='ArrowDown') i++; else if(key==='ArrowUp') i--; else return false; setSelected(i = Math.max(0,Math.min(elements.length-1,i))); e.preventDefault(); return true; }; } }); .element{ background: gray; width:200px; padding:10px; margin-bottom:1px; } .element.active{ background: red; } <section> <div class="element">BOX</div> <div class="element">BOX</div> <div class="element">BOX</div> <div class="element">BOX</div> <div class="element">BOX</div> <div class="element">BOX</div> </section>