He estado trabajando en una calculadora JS simple usando un enfoque OOP. Estoy luchando por crear una solución que evite la entrada de decimales adicionales. Por ejemplo, un usuario puede ingresar 3.2.1.5. Idealmente, esta calculadora mostraría la expresión completa en la pantalla de la calculadora digital antes de resolverla y devolver el resultado. Con esto en mente, simplemente evitar que un usuario agregue un segundo decimal evitaría que agregue (o cualquier operador que elija) varios decimales juntos. He considerado usar .split() y .join() en operadores en la entrada, pero está comenzando a complicarse ya que hay múltiples operadores a considerar. Idealmente, quiero evitar expresiones regulares.
const keys = document.querySelector('.calc-buttons'); keys.addEventListener('click', event => { const {target} = event const {value} = target if(!target.matches('button')){ return }else{ calculator.parseInput(value) //console.log(value) } }) const calculator = { displayText: '0', prevTotal: null, parseInput(value){ //have any of the special buttons(AC, decimal, =) been clicked? switch(value){ case '=': //calculate answer this.calcAnswer(this.displayText) break case 'AC': //clear screen & stored values this.clearAll() break case '.': //create decimal if(this.displayText == 0){ //pass'0.' this.addText('0.') }else{ //add value to text string this.addText(value) } break default: //add value to text string this.addText(value) break } }, addText(value){ if(this.displayText == '0'){ this.displayText = '' }else if(this.prevTotal !== null){ this.displayText = this.prevTotal this.prevTotal = null } //check if previous input is a number if(isNaN(+(value)) && isNaN(+(this.displayText))){ if(isNaN(this.displayText.slice(-1))){ return } }else if(value == '.' && this.displayText.slice(-1) == '.'){ return } this.displayText += value //output display text to screen this.outputText(this.displayText) }, outputText(text){ document.querySelector('.screen').value = text }, calcAnswer(equation){ let result = Function("return " + equation)() this.outputText(result) //console.log(equation) //console.log(result) this.prevTotal = result }, clearAll(){ this.displayText = '0', this.prevTotal = null this.outputText(this.displayText) } }Las funciones se basan en la respuesta de StepUp (lo cual es incorrecto AFAIK; debería ser .length > 2 pero aún no puedo comentar)
const hasManySymbols = (str, symbol) => { const firstIndex = str.indexOf(symbol) // find the first occurrence of the symbol if(firstIndex == -1) return false // if there is no first occurrence there are not many symbols return str.indexOf(symbol, firstIndex + 1) != -1 // whether or not there is a second occurrence } const validate = str => hasManySymbols(str, '.') ? 'invalid input' : 'valid input' console.log(validate('1.23')) // "valid input" console.log(validate('1.2.3')) // "invalid input"No estoy seguro de si esto es más rápido o más lento, pero en teoría debería ser más rápido, supongo.
Puede crear una función simple para evitar la repetición de código y ocultar detalles innecesarios en las funciones. Además, ayuda a reducir la convolución.
Por lo tanto, cree una función que verifique la elegibilidad de la entrada y, según el resultado, simplemente notifique al usuario o elimine el último carácter incorrecto.
El boceto de la función podría ser así:
const hasManySigns = (str, sign) => str.split(sign).length > 2Un ejemplo:
const hasManySigns = (str, sign) => str.split(sign).length > 2 let foo = '1.2.3' const validate = str => hasManySigns(str, '.') ? 'incorrect input' : 'correct input' console.log(validate(foo))