tengo tres botones Todo lo que necesito es agregar a la matriz un valor correspondiente haciendo clic en el botón , pero si el valor ya existe en mi matriz, debo eliminarlo de mi matriz. Mi código funciona solo si lo usamos dos veces (agregar y eliminar) el mismo botón. Pero si lo usamos con diferentes, se rompe. Pruébelo con el ejemplo a continuación. ¿Cuál es la razón de ese comportamiento?
Solo JavaScript puro.
let buttons = document.querySelectorAll('.string') let array = [] let value = '' buttons.forEach(el => el.addEventListener('click', () => { value = el.innerHTML for (i = 0; array.length + 1; i++) { if (array[i] === value) { delete array[i] array = array.filter(x => x) // clear empty values console.log('deleted', array) } else { array.push(value) console.log('added', array) } break } })) <div class="block"> <div class="string">some</div> <div class="string">else</div> <div class="string">other</div> </div>No funciona como espera porque si el valor no coincide con el primer elemento de la matriz, se empuja y el bucle se interrumpe. (Tu bucle siempre se rompe después del primer índice de todos modos...)
En su lugar, puede usar Array.prototype.indexOf para obtener el índice del elemento si existe en la matriz y luego eliminar ese índice si existe o empujarlo si no lo hace.
También puede usar Array.prototype.splice(index, deleteCount) para eliminar el índice que no desea en lugar de delete y Array.prototype.filter .
let buttons = document.querySelectorAll('.string') let array = [] let value = '' buttons.forEach(el => el.addEventListener('click', () => { value = el.innerHTML let i = array.indexOf(value); if(i > -1) { array.splice(i, 1); console.log('deleted', array) } else { array.push(value) console.log('added', array) } })) <div class="block"> <div class="string">some</div> <div class="string">else</div> <div class="string">other</div> </div>Si tenía su corazón puesto en usar un ciclo for en su lugar, también arreglé su fragmento original para que funcione usando el ciclo que tenía:
let buttons = document.querySelectorAll('.string') let array = [] let value = '' buttons.forEach(el => el.addEventListener('click', () => { value = el.innerHTML if(array.length < 1) { array.push(value) console.log("added", array) return } for (i = 0; i < array.length; i++) { if (array[i] === value) { array.splice(i, 1) console.log('deleted', array) break } else if (i == array.length - 1) { array.push(value) console.log('added', array) break } } })) <div class="block"> <div class="string">some</div> <div class="string">else</div> <div class="string">other</div> </div>1) Puede hacerlo más eficiente si usa Establecer aquí, porque acceder al valor es mucho mejor que acceder al valor desde la matriz.
2) Es mejor usar textContent en lugar de innerHTML .
let buttons = document.querySelectorAll('.string') let array = []; const set = new Set(); buttons.forEach(el => el.addEventListener('click', () => { const text = el.textContent; if (!set.has(text)) { set.add(text); array.push(text); } else { const index = array.indexOf(text); array.splice(index, 1); set.delete(text); } console.log(array); })) <div class="block"> <div class="string">some</div> <div class="string">else</div> <div class="string">other</div> </div>