1

Mi idea es hacer un botón que al presionarlo ejecute una función que sume 2 números que serán los valores de 2 inputs del formulario pasando estos como parámetros de la función. Se hacerlo colocando onclick en el boton dentro del archivo html pero mi idea es hacerlo todo en un fichero js externo.

Tengo esto en mi archivo HTML:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>evento onclick</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <h1>evento onclick</h1>
    <form name="ejercicio1">
        <fieldset>
            <legend>Ejercicio 1</legend>
            <label for="e1n1">Inserta 2 números para sumarlos</label>
            <input type="number" id="e1n1" name="nombre">
            <input type="number" id="e1n2" name="nombre">
            <input type="button" id="e1calc" value="calcular">
        </fieldset>
    </form>
    <script src="scripts.js"></script>
</body>

Tengo esto en mi archivo js:

document.addEventListener('DOMContentLoaded', function() {
    // form1
    const f1numero1 = document.getElementById('e1n1');
    const f1numero2 = document.getElementById('e1n2')
    const f1calcular = document.getElementById('e1calc');
    // functions
    const suma = (a, b) => {
        resultado = a+b
        return alert(resultado);
    }
    //events
    f1calcular.document.addEventListener('onclick', suma(f1numero1.value, f1numero2.value));
});

Gracias de antemano

Dazai_red
  • 37
  • 5

3 Answers3

1

Es una muy buena práctica el querer sacar los eventos del HTML, de hecho las buenas prácticas lo recomiendan.

Pero, realmente no necesitas pasar parámetros en este caso. Eso hace el código aún un poco dependiente. Dado que en el contexto tienes referencia de los valores (lo cual también es una buena práctica). Puedes usar esa referencia para hacer la suma.

Otro error en tu código es que sigues usando document para asignar el listener. Precisamente creaste la referencia para no volver a usar document (ese es el sentido de la buena práctica, crear referencias para no molestar al DOM cada vez que quieras referirte a ese elemento).

Otro error es que en la escucha de eventos se usa click para este caso, no onclick.

Oootro error es que debes convertir los valores a entero para sumarlos (con parseInt() si se trara de enteros o parseFloat() si tuvieran decimales). En el ejemplo implementé parseInt() pero lo puedes cambiar según el caso.

Y, tu forma de crear sumar se parece al viejo estilo, como indica MDN. Hoy día no es necesario escribir código así, cuando puedes implementar una sintaxis más clara.

Aquí asignamos mediante una función aparte:

document.addEventListener('DOMContentLoaded', function() {
  // form1
  const f1numero1 = document.getElementById('e1n1');
  const f1numero2 = document.getElementById('e1n2');
  const f1calcular = document.getElementById('e1calc');

  f1calcular.addEventListener('click', suma, false);

  function suma() {
    /*
      Con este pequeño truco conviertes a entero
      y a la vez evitas NaN en valores no numéricos, porque el || convierte a 0 los casos NaN
    */
    let numA = parseInt(f1numero1.value) || 0;
    let numB = parseInt(f1numero2.value) || 0;
    console.log(numA + numB);
  }

});
<h1>evento onclick</h1>
<form name="ejercicio1">
  <fieldset>
    <legend>Ejercicio 1</legend>
    <label for="e1n1">Inserta 2 números para sumarlos</label>
    <input type="number" id="e1n1" name="nombre">
    <input type="number" id="e1n2" name="nombre">
    <input type="button" id="e1calc" value="calcular">
  </fieldset>
</form>

Pero también puedes hacerlo de este modo:

document.addEventListener('DOMContentLoaded', function() {
  // form1
  const f1numero1 = document.getElementById('e1n1');
  const f1numero2 = document.getElementById('e1n2');
  const f1calcular = document.getElementById('e1calc');
  
  f1calcular.addEventListener("click", function() {

    /*
      Con este pequeño truco conviertes a entero
      y a la vez evitas NaN en valores no numéricos, porque el || convierte a 0 los casos NaN
    */
    let numA = parseInt(f1numero1.value) || 0;
    let numB = parseInt(f1numero2.value) || 0;
    console.log(numA + numB);  
  

});

  

});
<h1>evento onclick</h1>
<form name="ejercicio1">
  <fieldset>
    <legend>Ejercicio 1</legend>
    <label for="e1n1">Inserta 2 números para sumarlos</label>
    <input type="number" id="e1n1" name="nombre">
    <input type="number" id="e1n2" name="nombre">
    <input type="button" id="e1calc" value="calcular">
  </fieldset>
</form>
A. Cedano
  • 86,578
  • 19
  • 122
  • 221
  • Ok gracias por las aclaraciones igualmente lo de querer usar parámetros es más por si tengo varios formularios en un mismo documento html y quiero reutilizar esa función suma en algún otro sin tener que escribir el código de esa función otra vez como podría hacerlo en ese caso? – Dazai_red May 23 '21 at 20:59
  • 1
    @Dazai_red en ese caso puedes asignar el listener a cada botón de cada formulario, lo cual te permitiría usar una misma función en diferentes escenarios. Pero en ese caso te recomendaría usar otro tipo de selectores para los input (por ejemplo un selector de clase), porque el ID no se debería repetir en los elementos. Imagina que pones a los inputs la clase `operandos` por ejemplo, podrías recoger por ese selector el valor de todos los inputs que tengan `class="operandos"` en un contexto determinado y sumar sus valores. Es sólo un ejemplo del amplio alcance de los eventos y selectores. – A. Cedano May 23 '21 at 21:18
1

El siguiente código funciona, pero dependiendo de lo que necesites, tal vez debas usar paseFloat( ) en lugar de parseInt( )

window.addEventListener('load', (event) => {
  alert('page is fully loaded');
    // form1
    const f1numero1 = document.getElementById('e1n1');
    const f1numero2 = document.getElementById('e1n2')
    const f1calcular = document.getElementById('e1calc');
    // functions

    //events
    document.getElementById("e1calc").addEventListener("click",
  function() {
    alert(
      parseInt(document.getElementById('e1n1').value) + parseInt(document.getElementById('e1n2').value)
    )
  }
);
});
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>evento onclick</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <h1>evento onclick</h1>
    <form name="ejercicio1">
        <fieldset>
            <legend>Ejercicio 1</legend>
            <label for="e1n1">Inserta 2 números para sumarlos</label><br>
            <input type="number" id="e1n1" name="nombre"><br>
            <input type="number" id="e1n2" name="nombre"><br>
            <input type="button" id="e1calc" value="calcular">
        </fieldset>
    </form>
    <script src="scripts.js"></script>
</body>
JStark
  • 11
  • 2
  • 1
    Deberías diferenciar entre `window` y `document`. Para este caso **no se justifica escuchar el load de la ventana, debe escucharse el load del documento**. [Ver aquí para más detalles](https://es.stackoverflow.com/q/51946/29967). – A. Cedano May 22 '21 at 10:56
  • Por supuesto puedes poner el onclick event listener, dentro del window.onload – JStark May 22 '21 at 10:56
  • No me refiero a eso. El `window` es un elemento superior al `document` y todos los elementos que se necesitan aquí están en el `document`, por tanto, no se justifica escuchar la carga del `window` para esto. – A. Cedano May 22 '21 at 10:59
  • Got it, thanks. – JStark May 22 '21 at 11:04
1

Otra manera separando las funciones :

 const agregarEventoClickAlBoton = () => {  
   document.getElementById("e1calc").addEventListener("click", sumarNumeros)
 
 }
 
 const sumarNumeros = () => {
  const num1 = document.getElementById("e1n1").value
  const num2 = document.getElementById("e1n2").value
  const resultado = Number(num1) + Number(num2)
  alert(resultado)
 }
 
 
document.addEventListener("DOMContentLoaded", agregarEventoClickAlBoton)
davidbug
  • 480
  • 2
  • 5