Computing">
JavaScript
JavaScript
Lenguajes de marcas
Desarrollo de Aplicaciones Web Lenguajes de Marcas
Tema 6. JavaScript
1. Introducción
JavaScript es un lenguaje interpretado. Se utiliza principalmente en el lado del cliente,
implementado como parte de un navegador web, aunque actualmente es posible ejecutar
JavaScript en el propio servidor (NodeJS).
Se diseñó con una sintaxis similar al lenguaje C, aunque adopta nombres y convenciones
de Java. Sin embargo Java y JavaScript no están relacionados.
Posteriormente, Netscape firmó una alianza con Sun para el desarrollo del nuevo lenguaje
de programación al que decidió cambiar el nombre por el de JavaScript.
2
Desarrollo de Aplicaciones Web Lenguajes de Marcas
2. Sintaxis
La sintaxis de JavaScript es muy similar a la de lenguajes como Java y C. Sus normas básicas
son las siguientes:
No tiene en cuenta los espacios en blanco y las nuevas líneas por lo que el código
se puede ordenar tabulando las líneas, añadiendo espacios, creando nuevas líneas,
etc, para entenderlo mejor.
Distingue entre mayúsculas y minúsculas.
No define el tipo de las variables. Una misma variable puede almacenar diferentes
tipos de datos durante la ejecución del script.
No es necesario terminar cada sentencia con “;” pero es conveniente.
Al incluir comentarios su contenido no se visualiza por pantalla, pero sí que se
envía al navegador junto con el resto del script, por lo que hay que tener cuidado
con la información que contengan. Los comentarios se definen de dos formas:
3
Desarrollo de Aplicaciones Web Lenguajes de Marcas
4
Desarrollo de Aplicaciones Web Lenguajes de Marcas
prompt()
Utilizando este método se mostrará al usuario un mensaje en una ventana modal
solicitando información. De la misma forma que el método alert, el foco pasa a la nueva
ventana y no se puede continuar accediendo a otras partes de la página.
confirm()
Al utilizar este método se mostrará por pantalla un mensaje de alerta para su confirmación
o cancelación, de nuevo en una ventana modal. Al igual que los dos métodos anteriores, el
foco pasa a la ventana modal.
Este método devuelve true si el usuario acepta el mensaje y false en caso contrario.
[Link]("Mensaje de consola.");
[Link]("Mensaje informativo.");
[Link]("Mensaje de aviso.");
[Link]("Mensaje de error.");
[Link]();//Para limpiar la consola
EJERCICIO 2
Modifica la página y los scripts del ejercicio 1 para que:
5
Desarrollo de Aplicaciones Web Lenguajes de Marcas
Informe al usuario mediante un alert de que no ha escrito su
nombre.
o Por el contrario, si no es un valor vacío, pida confirmación del nombre
mostrándoselo. En caso de que el usuario confirme:
Se mostrará un log por consola con el texto “El nombre es
correcto”.
Se muestre un alert con el texto “Bienvenido”.
o Y como última opción, en caso de que el usuario no confirme su nombre,
se mostrará un warning por consola con el texto “No se sabe su nombre”.
6
Desarrollo de Aplicaciones Web Lenguajes de Marcas
La declaración con var define una variable en el ámbito local actual (función) y se hereda a
elementos descendientes por referencia(bloques por ejemplo). Si la variable es declarada
fuera de una función, o dentro de ella pero sin la palabra var, la variable será global.
Si se declara una variable con let o const tendrá alcance de bloque y no será visible para la
función que lo contenga. La variable declarada con const no podrá ser reasignada.
El nombre de una variable podrá contener letras, números, guiones bajos o símbolos dólar
($) y no podrá comenzar por número. Es recomendable que se siga la sintaxis
lowerCamelCase(esteEsUnEjemploDeNombre). Su contenido podrá ser:
Tipos de datos
Los tipos de datos que define el estándar son:
Tipos primitivos:
o Boolean: tomará los valores true o false.
o Null: tendrá el valor null.
o Undefined: Se trata de una variable a la que no se le ha asignado valor.
Tendrá el valor undefined.
7
Desarrollo de Aplicaciones Web Lenguajes de Marcas
oNumber: número entre -(253 -1) y 253 -1. Además, tiene tres valores
simbólicos: +Infinity, -Infinity, and NaN.
o String: Cadena de texto. Irá entre comillas. Una vez creada, la cadena, no
es posible modificarla. Pero si es posible crear otra basándose en una
operación de la cadena original. Por ejemplo:
[Link]():seleccionar una subcadena de la original.
[Link](): concatenar dos cadenas existentes.
o Symbol: Tipo nuevo de la última versión. Se trata de un valor primitivo
único e inmutable y puede ser usado como la clave de una propiedad de
un Object.
Tipos Object:
o Un objeto es una colección de propiedades, una lista de pares clave-valor
donde la clave será un String o un Symbol y el valor cualquier tipo de dato.
Un ejemplo sencillo de objeto sería:
var usuario= { id: 5, fechaReg: “22/02/2019”, nombre: Elena };
y para acceder a uno de sus valores:
[Link];
o Además, existe un conjunto de objetos especiales como puede ser el
“objeto global”, el “objeto prototipo”, los arrays, las funciones, las clases
definidas por el programador, las clases predefinidas JavaScript (Date,
Error entre otras) y otros.
EJERCICIO 3
Realiza los cambios necesarios en el archivo [Link] del ejercicio 1 para que se
muestren alertas con la información que se genere en cada paso:
Incluir un título en el documento HTML que capture el evento onclick:
o Añadir el atributo del elemento h1: > Crear la función mostrarVariables en el fichero .js de la siguiente manera:
function mostrarVariables() { }
Ya dentro de la función:
o Mostrar una alerta con el valor de la variable variable1(sin declararla primero).
alert('Variable1: ' + variable1);
o Asignar a la variable(sin declarar primero) variable2 el valor null y mostrarlo
seguidamente mediante una alerta.
o Declarar la variable variable1 y en la misma sentencia asignarle el valor 34.
Mostrarlo después mediante una alerta.
o Asignar a la variable(sin declarar primero) variable3 el valor 15,9 y
seguidamente mostrar una alerta con la multiplicación de variable1 y
variable3. (variable1*variable3)
o Asignar a variable3 la cadena de texto “ahora soy un texto”. Mostrarlo
seguidamente mediante una alerta.
8
Desarrollo de Aplicaciones Web Lenguajes de Marcas
Luego hay elementos, como la función prompt(), que devuelven siempre cadenas, y para
casos como este existen funciones de conversión de datos. Algunas de las más usadas son:
parseInt(5.7) // Devuelve 5
parseInt('5.7') // Devuelve 5
parseInt('5 coches') // Devuelve 5, Number devolvería NaN
parseFloat(valor): Igual que el anterior pero a número decimal.
Boolean(valor): Convierte cualquier valor a booleano. Cualquier valor se evaluará a
true excepto 0, NaN, null, undefined o cadena vacía (‘’) que se evaluarán a false.
EJERCICIO 4
4.3. Operadores
Un operador es básicamente un símbolo matemático que puede actuar sobre dos valores
(o variables) y producir un resultado. Los tipos de operadores más comunes en JavaScript son:
Operadores aritméticos: Sirven para realizar operaciones aritméticas con valores y/o
variables.
Operadores comparativos: Para establecer comparaciones entre valores y/o variables.
Operadores lógicos: Se utilizan para establecer condiciones.
9
Desarrollo de Aplicaciones Web Lenguajes de Marcas
Operadores aritméticos
Operadores lógicos
> Mayor que var1 > var2 true si var1 mayor que var2
< Menor que var1 < var2 true si var1 menor que var2
== Igual a var1 == var2 true si var1 igual que var2
!= Distinto de var1 != var2 true si var1 distinta que var2
>= Mayor o igual a var1 >= var2 true si var1 mayor o igual que var2
<= Menor o igual que var1 <= var2 true si var1 menor o igual que var2
=== Idéntico a var1 === var2 true si ambas son idénticas, es decir,
si sus valores coinciden y son del mismo tipo de
variable
!== No idéntico a var1 !== var2 true si no son idénticas, es decir, si
sus valores no coinciden o no son del mismo tipo de
variable
Hay que tener en cuenta que:
Operadores condicionales
10
Desarrollo de Aplicaciones Web Lenguajes de Marcas
EJERCICIO 5
Habiendo declarado las variables var1 y var2 como cadenas de texto con
valor(comparar diferentes resultados, se puede meter todo en un mismo alert):
o var1==var2.
o var1!=var2.
o var1<var2.
o var1>var2.
o var1<=var2.
o var1>=var2.
Ahora, siendo var3 un valor numérico, y var4 una cadena cuyo texto son números,
compara los resultados si pones lo siguiente:
o var3==var4.
o var3===var4.
Siendo var5, var6 y var7 valores numéricos:
o Mostrar el resultado de var5<var6 y var6<var7.
o Mostrar el resultado de var5<=var6 y var6>var7.
o Asignar a var7 !true y mostrarlo.
11
Desarrollo de Aplicaciones Web Lenguajes de Marcas
5. Arrays
Un array es un tipo especial de object que se utiliza para almacenar más de un valor en
una sola variable. En un array se usan índices numéricos y en los objetos nombres.
Los arrays pueden almacenar múltiples valores bajo un mismo nombre, y se podrá acceder
a cada valor mediante un índice numérico. Las dos formas siguientes de declaración hacen
exactamente lo mismo, aunque es más simple y rápida en ejecución la primera de ellas.
alert(num3);
alert(variables[0] +"---"+ variables[5]);
alert(variables);
Un array puede almacenar valores de distintos tipos en cada elemento. Y pueden
almacenar objetos, funciones u otros arrays además de los tipos primitivos:
Mediante la función sort(), se ordena un array alfabéticamente, por lo que no servirá para
ordenar arrays con valores numéricos(si los hay, los tratará como cadenas de números).
deportes[[Link]] = "atletismo";
12
Desarrollo de Aplicaciones Web Lenguajes de Marcas
Y para eliminar la última posición de un array, se puede hacer uso de la propiedad pop,
que devolverá el valor eliminado:
[Link]();
EJERCICIO 6
13
Desarrollo de Aplicaciones Web Lenguajes de Marcas
[Link](1, 2);
Inserción o reemplazo: Se puede insertar elementos en un array indicando la
posición donde se van a agregar, el número de elementos a eliminar y el elemento
a insertar. Opcionalmente, se puede especificar una cuarta, quinta, o cualquier
número de otros parámetros a insertar:
Prueba todos los ejemplos del apartado de arrays, sacando por consola el
resultado de cada cambio.
Si se explica algún caso que no esté en los ejemplos incluirlo también.
Implementa una función que incluya en un array la siguiente lista: tela, bies, hilo,
tijeras, máquina de coser, botón. Después, utilizando las funciones vistas:
o Elimina el bies. Muestra el array por consola.
o Añade, entre hilo y tijeras, hilo torzal. Muéstralo de nuevo por consola.
o Quita tijeras y sustitúyelas por cúter rotatorio y mesa de corte. Una vez
mas, muestra el array por consola.
o Crea, a partir del primer array, dos nuevos donde el primero incluya los
tres primeros elementos del original y el segundo del cuarto al sexto.
o En el segundo de los nuevos array creados:
Incluye, en la primera posición, remalladora.
Incluye, en la penúltima posición, cinta métrica.
o Muestra por consola el contenido de los tres arrays.
14
Desarrollo de Aplicaciones Web Lenguajes de Marcas
Las variables que declaramos con var, no tienen alcance de bloque, es decir, si declaro
dentro de un bloque una variable, al salir de ese bloque el valor seguirá siendo visible:
var var1 = 1;
{
var1 = 2;
}
alert(var1); // mostrará 2
En resumen, la declaración con var define una variable en el ámbito local actual (función) y
se hereda a elementos descendientes por referencia(bloques por ejemplo). Si la variable es
declarada fuera de una función, la variable será global.
Sin embargo, si declaramos las variables con let o const, si tendrán alcance de bloque. Si
declaramos una variable con let o const dentro de un bloque, la variable pertenece solo a ese
bloque y no será visible para la función que lo contenga.
La diferencia entre estas dos última opciones radica en que con const no es posible
reasignar la variable. Si se intenta reasignar una variable constante se obtendrá un error tipo
TypeError:
const i = 0;
i = 1; //Al hacer esta asignación dará un error de tipo TypeError
Se puede concluir que, en general, let se usaría dentro de un bloque, función o ámbito
global, const para variables que no van sufrir reasignación y var para usos esporádicos.
6.1. If / if..else
Si se cumple la condición especificada, se ejecutará el bloque entre llaves. En caso de que
no se cumpla, se ejecutará el bloque indicado por el else (en caso de que se haya incluido).
Para una única sentencia, los paréntesis no son obligatorios, pero si recomendables:
if (condición) {
sentencia1;
}else {
sentencia2;
sentencia3;
}
15
Desarrollo de Aplicaciones Web Lenguajes de Marcas
6.2. switch
Permite listar una serie de bloques de enunciados que se ejecuten dependiendo del valor
de una variable. El valor se comprobará usando comparación estricta, ===:
switch (variable){
case 1:
sentencias;
break;
…
case n:
sentencias;
break;
default:
sentencias;
break;
}
switch (var1) {
case 'uno':
case 'dos':
case 'tres':
case 'cuatro':
[Link]('menor que 5');
break;
case 'cinco':
case 'seis':
[Link]('mayor o igual que 5');
break;
}
16
Desarrollo de Aplicaciones Web Lenguajes de Marcas
La sentencia for..in, por su parte, se suele utilizar para recorrer un objeto pasando por
cada una de sus propiedades para actuar sobre ellas de alguna manera. Además, como en
Javascript los arrays son también objetos, se podrá utilizar para iterar por cada uno de los
valores de estos últimos.
En este ejemplo, utilizamos for..in para mostrar datos de un objeto. Se mostrará el nombre
de la propiedad, para mostrar su valor habría que acceder a través de ese nombre utilizándolo
como índice.
var obj1 = {
var1 : 1,
var2 : 2,
var3 : 3
}
for( var property in obj1 ){
[Link]( property );
}
Un array se puede recorrer también haciendo uso de su método foreach(), donde para
cada elemento se hará una llamada a la función que se indique(más adelante, cuando veamos
funciones, veremos como declarar la función en cuestión):
[Link](element => [Link](element));
6.4. do…while
El bucle do…while tiene el mismo comportamiento que un bucle for solo que primero se
ejecutan las sentencias y después se evalúa la condición, por lo que siempre se va a ejecutar
una vez como mínimo.
do{
sentencias
} while (condición);
En este caso, habría que declarar el contador fuera del bloque para poder utilizarlo.
17
Desarrollo de Aplicaciones Web Lenguajes de Marcas
6.5. while
Mismo comportamiento que en el caso anterior, do…while, salvo que en este caso la
sentencia se evalúa antes de la ejecución de cualquier sentencia.
while (condicion) {
sentencias
}
EJERCICIO 8
Teniendo en cuenta que se puede utilizar la función prompt() para pedir valor por pantalla
al usuario, utiliza las diferentes estructuras de control para lo siguiente:
Crea un array con el nombre de los doce meses. Muéstralos por pantalla o por
consola uno a uno.
Pide al usuario que introduzca un número. Calcula el factorial de ese número y
mostrarlo por pantalla. ** prompt() recoge cadenas siempre, por lo que utiliza la
función Number() para pasarlo a valor numérico.
Pide al usuario que introduzca su edad, y dependiendo del valor que introduzca
muestra por pantalla una recomendación de Netflix:
o Si es menor de 6 años: Patrulla Canina.
o Si está entre 7 y 13 años: Alexa y Katie.
o Si tiene entre 13 y 18: Anne with an E
o Si tiene entre 19 y 35: Stranger Things
o Si tiene más de 35: Sherlock
Crea un bucle del que solo se salga si el usuario mete un número comprendido
entre 45 y 72.
La instrucción break dentro de un bucle hace que la ejecución del mismo se interrumpa
inmediatamente y continúe el programa inmediatamente a continuación del final del bucle.
18
Desarrollo de Aplicaciones Web Lenguajes de Marcas
var numVeces = 1;
var palabra;
while (numVeces <= 5) {
palabra = prompt("Escribe la palabra Coche ");
[Link]("Intento número " + numVeces);
numVeces++;
if (palabra == "Coche") {
[Link](palabra);
break;
}
}
var eleccion;
for (var i = 0; i < 10; i++) {
[Link](" Valor del contador: " + i);
eleccion = confirm("¿Terminar la ejecución de la iteración?");
if (eleccion)
continue;
[Link]("Se realiza un incremento extra del contador");
i++;
}
EJERCICIO 9
Prueba, en la consola del navegador, los dos ejemplos de las sentencias break y
continue.
Define una función donde se pida, repetidamente, al usuario que introduzca un
color. Utiliza las sentencias break y continue donde corresponda:
o Si el color introducido es el rojo, la ejecución saldrá del bucle.
o Si el color indicado es el verde, se volverá al comienzo del bloque sin
ejecutar las sentencias siguientes.
o Si se trata de cualquier otro color, se incluirá éste en un array. Si el color
ya estuviera se repite.
o Tras terminar la ejecución del bucle se mostrará por pantalla el número de
veces que el usuario ha introducido un color y todos los valores
almacenados en el array.
19
Desarrollo de Aplicaciones Web Lenguajes de Marcas
7. Funciones
Una función es un fragmento de código que puede ser invocado para realizar tareas y/o
devolver un resultado. Esta división del código en funciones es efectiva a la hora de resolver
problemas complejos. Además una función se puede llamar tantas veces como se desee, lo
cual evita repetición de código, y permite un mantenimiento de código mas sencillo.
En JavaScript, las funciones son objetos, es decir, se pueden manipular y transmitir al igual
que cualquier otro objeto. Concretamente son objetos de tipo Function.
También se podrá crear una expresión de función(una función anónima) que se asigna a
una variable. En este caso, la función no estará disponible hasta que no se ejecute esa línea:
function suma(a,b,c){
return a+b+c;
}
function principal() {
var suma = Suma(4,6,2);
}
Si a una función se le pasan más parámetros de los que ha definido, se ignorarán los
parámetros sobrantes. Por el contrario, si se pasan menos parámetros de los necesarios,
JavaScript asignará valor undefined a los parámetros de los que falta el valor y se ejecutará sin
que surja ningún mensaje de error (aparte de los posibles resultados extraños que esto
pudiera ocasionar).
20
Desarrollo de Aplicaciones Web Lenguajes de Marcas
EJERCICIO 10
21
Desarrollo de Aplicaciones Web Lenguajes de Marcas
8. DOM
DOM(Document Object Model) permite identificar cada elemento de una página web para
poder manipularlo y modificar sus propiedades, e incluso mostrarlo o no dependiendo de las
necesidades de cada momento y situación.
El W3C definió el estándar DOM que define qué elementos se considera que conforman
una página web, cómo se nombran, cómo se relacionan entre sí, cómo se puede acceder a
ellos, etc. Cuando se carga una página web, el navegador crea un modelo de objetos de la
misma. El modelo se construye como un árbol de objetos, donde cada elemento es un nodo:
A partir de este modelo, JavaScript puede cambiar los elementos y atributos de la página,
cambiar los estilos CSS, eliminar elementos y atributos HTML, añadir nuevos elementos y
atributos, reaccionar a todos los eventos que se produzcan en la página, crear nuevos eventos
HTML, etc.
El estándar establece Core DOM para todo tipo de documentos, XML DOM para
documentos XML y HTML DOM para documentos HTML.
Los métodos de HTML DOM son acciones que se pueden ejecutar sobre elementos HTML,
mientras que las propiedades son valores de elementos HTML que se puede establecer o
eliminar.
22
Desarrollo de Aplicaciones Web Lenguajes de Marcas
getElementById()
La manera más habitual de acceder a un elemento HTML es a través de su id:
[Link]("div1");
Con esto se recupera el elemento completo, no solo su valor. Para poder recuperarlo
habría que utilizar otros métodos o propiedades sobre el elemento recuperado en primera
instancia.
getElementsByTagName()
Mediante este método, se puede recuperar una lista de elementos con un nombre
determinado. Si se le pasa como argumento la cadena "*" se estarán pidiendo todos los
elementos.
[Link](“h1”);
[Link](“h1”)[0];
getElementsByClassName()
Similar al anterior, permite recuperar una lista de elementos a partir de uno o varios
nombre de clase. Si se pone más de uno se separarán por espacios.
innerHTML
La forma más fácil de acceder al contenido de un elemento es a través de ésta propiedad,
ya sea para recuperar el contenido o para cambiarlo:
23
Desarrollo de Aplicaciones Web Lenguajes de Marcas
[Link]("boton1").setAttribute("requiered","");
[Link]("texto1").setAttribute("value","Primero");
Por su parte, getAttribute() devuelve el valor del atributo que se le haya pasado como
parámetro.
[Link]("H1")[1].removeAttribute("value");
Se puede dar el caso en que sea necesario sustituir un elemento por otro. Esto es posible
utilizando el método replaceChild().
[Link](nuevoElemento, elementoViejo);
24
Desarrollo de Aplicaciones Web Lenguajes de Marcas
EJERCICIO 11
[Link]("titulo1").[Link] = "green";
[Link]("titulo1").[Link] = "2px green dotted";
Normalmente no se asignan estilos concretos a un elemento a través de DOM, sino que se
añaden(o eliminan) valores al atributo class del elemento en cuestión:
[Link]("class", "nombreDeClase");
[Link] = "nombreDeClase2";
En el ejemplo anterior se modifica el valor del atributo class, pero es posible añadir o
quitar una clase concreta sin eliminar el resto:
EJERCICIO 12
Siguiendo con la página creada en el ejercicio 11, se va a trabajar con el cambio de estilo.
Para llevar a cabo todos los cambios de estilo haz uso de clases, no asignes estilos de manera
individual.:
25
Desarrollo de Aplicaciones Web Lenguajes de Marcas
Hay un objeto que no obedece a estas reglas, se trata del objeto window. Éste representa
la ventana que contiene un documento DOM, por lo que no es parte del árbol DOM, es más, el
árbol DOM será hijo del objeto window. El objeto window al que pertenece un documento
puede ser obtenido usando la propiedad [Link].
Teniendo en cuenta lo anterior, vamos a ver diferentes maneras de acceder a los objetos y
su contenido.
26
Desarrollo de Aplicaciones Web Lenguajes de Marcas
<h1 id="tit1">Título1</h1>
[Link]("tit1").innerHTML;
[Link]("tit1").[Link];
[Link]("tit1").childNodes[0].nodeValue;
Y las tres opciones devolverán lo mismo. Nota que el texto se considera el contenido de un
nodo hijo(nodeValue), el cual será un nodo de tipo texto.
Y sabiendo que el texto que contiene un elemento realmente es otro objeto de tipo texto,
también podemos crear ese objeto mediante createTextNode(), y añadirlo a cualquier otro
como un hijo, haciendo:
Si como segundo elemento se le pasa null, el nuevo elemento se añadirá como último hijo
del padre.
27
Desarrollo de Aplicaciones Web Lenguajes de Marcas
EJERCICIO 13
Copiar el resultado del ejercicio 11 en otro fichero JavaScript. Sobre la copia realizar las
modificaciones necesarias para que, una vez creada la lista, se ejecute un bucle en el que se
realice lo siguiente:
28
Desarrollo de Aplicaciones Web Lenguajes de Marcas
9. Eventos
Los eventos son acciones u ocurrencias que suceden y de los que el sistema, aplicación o
página que se está desarrollando avisa, por lo que, si es necesario, se puede definir una
respuesta a los mismos.
Los eventos se lanzan en la ventana del navegador, y suelen estar relacionados con un
elemento concreto de la misma que puede ser un elemento solo, un grupo de elementos, el
documento HTML cargado en la pestaña o la página entera.
No todos los eventos tienen acción por defecto, pero si se quiere dar una o cambiar la
existente, hay que capturarlos. Para capturar un evento sobre un objeto, se asigna una función
específica para manejar el evento cuando este ocurra.
EJERCICIO 14
Crear una página HTML con un formulario que pida el nombre de usuario, la contraseña, la
edad, el sexo mediante radiobuttons y que tenga botones de limpiar y enviar formulario:
Una vez que la página haya terminado de cargar, mostrar un mensaje por pantalla
que pregunte al usuario si es mayor de edad.
o En caso de que lo sea, introducir un nuevo campo llamado nº cuenta
debajo del campo edad.
Cuando el foco se ponga en el campo contraseña, el borde del campo cambia de
color.
29
Desarrollo de Aplicaciones Web Lenguajes de Marcas
Cuando el ratón pase por encima de cualquier nombre de los campos del
formulario, se cambiará el tamaño de letra a una mayor.
Cuando se envíe un formulario, se capturará el evento para que, antes de enviarlo
definitivamente, se pida confirmación al usuario:
o En caso de que cancele no se hará nada.
o En caso de que acepte el envío, realizarlo. Busca la manera en que se
lanzaría de nuevo el envío del formulario.
30