Hice una calculadora simple que toma la información ingresada por el usuario, luego realiza una acción con dos const y da el resultado en un seleccionado.
En total, tengo 5 entradas y 5 salidas. Para cada entrada y salida tengo 2 const.
El código se ve así:
const suprqMean = 3.93; const usabilityMean = 4.06; const suprqSD = 0.29; const usabilitySD = 0.29; { const input = document.querySelector("#formGroupExampleInput"); const log = document.getElementById("#suprq"); input.addEventListener("change", updateValue); function updateValue(e) { suprq.textContent = (e.target.value - suprqMean) / suprqSD; } } { const input = document.querySelector("#formGroupExampleInput1"); const log = document.getElementById("#usability"); input.addEventListener("change", updateValue); function updateValue(e) { usability.textContent = (e.target.value - usabilityMean) / usabilitySD; } } <form class="leftForm container"> <div class="form-group"> <label for="formGroupExampleInput">SUPR-Q raw</label> <input type="number" class="form-control" id="formGroupExampleInput" placeholder="SUPR-Q raw"> </div> <div class="form-group"> <label for="formGroupExampleInput2">Usability raw</label> <input type="number" class="form-control" id="formGroupExampleInput1" placeholder="Usability raw"> </div> </form> <table class="table table-striped table-dark"> <thead> <tr> <th scope="col">Z-Score</th> <th scope="col">Result</th> </tr> </thead> <tbody> <tr> <td>SUPR-Q:</td> <td id="suprq"></td> </tr> <tr> <td>Usability:</td> <td id="usability"></td> </tr> </tbody> </table>Y funciona, pero el código JS se ve horrible. ¿Hay alguna forma de optimizar el código JS? Quiero que el resultado se ingrese en tiempo real como funciona ahora.
Puede combinar las dos funciones en una al verificar e.target.id adentro, y seleccionar ambos valores de entrada a la vez para recorrer y agregar el detector de eventos:
const suprqMean = 3.93; const usabilityMean = 4.06; const suprqSD = 0.29; const usabilitySD = 0.29; document.querySelectorAll("[id^=formGroupExampleInput").forEach(el => { el.addEventListener("change", updateValue); }); function updateValue(e) { inpVer = e.target.id === "formGroupExampleInput" ? true : false; outEl = inpVer ? suprq : usability; outVal = inpVer ? (e.target.value - suprqMean) / suprqSD : (e.target.value - usabilityMean) / usabilitySD; outEl.textContent = outVal; } <form class="leftForm container"> <div class="form-group"> <label for="formGroupExampleInput">SUPR-Q raw</label> <input type="number" class="form-control" id="formGroupExampleInput" placeholder="SUPR-Q raw"> </div> <div class="form-group"> <label for="formGroupExampleInput2">Usability raw</label> <input type="number" class="form-control" id="formGroupExampleInput1" placeholder="Usability raw"> </div> </form> <table class="table table-striped table-dark"> <thead> <tr> <th scope="col">Z-Score</th> <th scope="col">Result</th> </tr> </thead> <tbody> <tr> <td>SUPR-Q:</td> <td id="suprq"></td> </tr> <tr> <td>Usability:</td> <td id="usability"></td> </tr> </tbody> </table>Parece que te estás repitiendo un poco en ese código JS.
El remedio habitual para esto sería refactorizar el código repetido en una función reutilizable:
const suprqMean = 3.93; const usabilityMean = 4.06; const suprqSD = 0.29; const usabilitySD = 0.29; function listenForChanges (inputId, logId, output, mean, SD) { const input = document.querySelector(inputId); const log = document.querySelector(logId); input.addEventListener("change", updateValue); function updateValue(e) { output.textContent = (e.target.value - mean) / SD; } } listenForChanges("#formGroupExampleInput", "#suprq", suprq, suprqMean, suprqSD) listenForChanges("#formGroupExampleInput1", "#usability", usability, usabilityMean, usabilitySD) Sin embargo, algo más se siente raro. En su fragmento original (y en el mío también) hay referencias a dos variables que nunca se declaran: suprq y usability .
Pero aparte de eso, ¿te gusta este uso de una función como primer paso para hacer el código un poco menos "horrible"?
Si tiene muchos de estos, el siguiente paso podría ser crear una estructura de datos para todos los pares de entrada y llamar a esta función en cada par con un bucle:
const all = [{ inputId: "#formGroupExampleInput", logId: "#suprq", output: suprq, mean: 3.93, SD: 0.29 }, { inputId: "#formGroupExampleInput1", logId: "#usability", output: usability, mean: 4.06, SD: 0.29 }] all.forEach(listenForChanges) function listenForChanges ({inputId, logId, output, mean, SD}) { const input = document.querySelector(inputId); const log = document.querySelector(logId); input.addEventListener("change", updateValue); function updateValue(e) { output.textContent = (e.target.value - mean) / SD; } } Tenga en cuenta que cambié un poco la función aquí, haciendo que acepte un solo parámetro de objeto en lugar de una serie de parámetros. Esto es solo para que sea más fácil unir todo con forEach .
Aquí hay una versión 'condensada'
const values = { suprqMean: 3.93, usabilityMean: 4.06, suprqSD: .29, usabilitySD: .29 }; ["suprq", "usability"].map((slug => { document.querySelector(`#${slug}Input`).addEventListener("change", (clicked => { document.getElementById(`${slug}`).textContent = (clicked.target.value - values[`${slug}Mean`]) / values[`${slug}SD`] })) })); <form class="leftForm container"> <div class="form-group"> <label for="formGroupExampleInput">SUPR-Q raw</label> <input type="number" class="form-control" id="suprqInput" placeholder="SUPR-Q raw"> </div> <div class="form-group"> <label for="formGroupExampleInput2">Usability raw</label> <input type="number" class="form-control" id="usabilityInput" placeholder="Usability raw"> </div> </form> <table class="table table-striped table-dark"> <thead> <tr> <th scope="col">Z-Score</th> <th scope="col">Result</th> </tr> </thead> <tbody> <tr> <td>SUPR-Q:</td> <td id="suprq"></td> </tr> <tr> <td>Usability:</td> <td id="usability"></td> </tr> </tbody> </table>