miércoles, 3 de enero de 2018

Javascript Parte LXXVI

El operador condicional ?: remplaza en algunos casos a estructuras if/else sencillas con el objetivo de escribir un código más compacto o corto.
Veamos primero un ejemplo resuelto con el if y luego modificado para emplear el operador condicional ?:
Problema
Cargar dos valores por teclado, luego almacenar en una variable el mayor de los dos valores ingresados.

<html>
<head>
</head>
<body>

<script type="text/javascript">

  var v1=prompt('Ingrese primer valor:','');
  var v2=prompt('Ingrese segundo valor:','');
  v1=parseInt(v1);
  v2=parseInt(v2);
  var mayor;
  if (v1>v2)
    mayor=v1;
  else
    mayor=v2;
  document.write('El mayor de los dos valores es:'+mayor);

</script>

</body>
</html>
Ahora el mismo problema pero empleando el operador codicional ?:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var v1=prompt('Ingrese primer valor:','');
  var v2=prompt('Ingrese segundo valor:','');
  v1=parseInt(v1);
  v2=parseInt(v2);
  var mayor;
  v1>v2 ? mayor=v1 : mayor=v2;
  document.write('El mayor de los dos valores es:'+mayor);

</script>

</body>
</html>
El operador ternario en el ejemplo lo podemos identificar en la siguiente línea:
  v1>v2 ? mayor=v1 : mayor=v2;
El operador ternario tiene la siguiente sintaxis:
  condición ? instrucción 1 : instrucción 2;
La condición es lo primero que indicamos a la izquierda del carácter "?". La condición siempre debe generar un resultado de tipo boolean (true/false)
Si la condición se verifica verdadera se ejecuta la instrucción 1, que es la que se encuentra a la izquierda del carácter ":", en cambio si la condición se verifica false se ejecuta la instrucción 2.

Javascript Parte LXXV

La función setTimeout y setInterval permiten pasar como primer parámetro el nombre de una función que se ejecutará después de una determinada cantidad de milisegundos que le pasamos en el segundo parámetro. La única diferencia entre estas funciones es que si llamamos a setInterval la función se ejecutará en forma repetida cada vez que pase dicha cantidad de milisegundos, en cambio con setTimeout solo llamará la función una única vez.
Estas dos funciones retornan un valor que será de utilidad si necesitamos eliminar la llamada a la función.
Problema Mostrar un cronómetro que comience en cero y se incremente en uno cada vez que pase un segundo. Disponer un botón para poder detener o reiniciar el cronómetro.
<!doctype html>
<html>
<head>
<title></title>

<script type="text/javascript">

  window.addEventListener('load', inicio, false);

  var reloj;

  function inicio() {
    reloj=setInterval(procesar,1000);
    document.getElementById('boton1').addEventListener('click',presionBoton,false);
  }

  function procesar()
  {
    var nro=parseInt(document.getElementById('cronometro').innerHTML);
    nro++;
    document.getElementById('cronometro').innerHTML=nro;
  }

  function presionBoton()
  {
    if (document.getElementById('boton1').value=='detener')
    {
      clearInterval(reloj);
      document.getElementById('boton1').value='continuar';
    }
    else
    {
      reloj=setInterval(procesar,1000);
      document.getElementById('boton1').value='detener';
    }
  }

</script>

<style>
  #cronometro {
    font-size:50px;
    color:#0a0;
  }
</style>

</head>
<body>

<span id="cronometro">0</span>
<br>
<input type="button" id="boton1" value="detener">
</body>
</html>
Definimos una variable global que guarde la referencia del timer, en la función inicio registramos la función que debe ejecutarse cada un segundo (1000 milisegundos):
  window.addEventListener('load', inicio, false);

  var reloj;

  function inicio() {
    reloj=setInterval(procesar,1000);
    document.getElementById('boton1').addEventListener('click',presionBoton,false);
  }
La función procesar se ejecuta cada un segundo, siempre y cuando se haya registrado esta función llamando a setInterval en la función inicio. El objetivo de esta función es extraer el valor del cronómetro, incrementarlo en uno y actualizarlo:
  function procesar()
  {
    var nro=parseInt(document.getElementById('cronometro').innerHTML);
    nro++;
    document.getElementById('cronometro').innerHTML=nro;
  }
La función presionBoton se ejecuta cada vez que lo presionamos y lo que hacemos es controlar la etiqueta del botón para ver si dice 'detener' con lo que llamando a la función clearInterval esto hace que se suprime la ejecución continua de la función procesar. Por el falso del if procedemos a registrar nuevamente la función procesar:
  function presionBoton()
  {
    if (document.getElementById('boton1').value=='detener')
    {
      clearInterval(reloj);
      document.getElementById('boton1').value='continuar';
    }
    else
    {
      reloj=setInterval(procesar,1000);
      document.getElementById('boton1').value='detener';
    }
  }

Javascript Parte LXXIV

La función isFinite verifica si el parámetro tiene un valor numérico finito, en caso afirmativo retorna true.
Una variable numérica puede almacenar alguno de los siguientes valores:
El número propiamente dicho.

El valor NaN

El valor Infinite

El valor -Infinite
Veamos un ejemplo almacenando valores en variables que nos generen los distintos valores posibles:
<html>
<head>
</head>
<body>
<script type="text/javascript">

  var x1=120;
  if (isFinite(x1)) //true
    document.write('x1 tiene un valor finito que es el '+x1);
  else
    document.write('x1 no tiene un valor finito que es el '+x1);
  document.write('<br>');
  var x2=10e399;
  if (isFinite(x2)) //false
    document.write('x2 tiene un valor finito que es el '+x2);
  else
    document.write('x2 no tiene un valor finito que es el '+x2);
  document.write('<br>');
  var x3=-10e399;
  if (isFinite(x3))  //false
    document.write('x3 tiene un valor finito que es el '+x3);
  else
    document.write('x3 no tiene un valor finito que es el '+x3);
  document.write('<br>');
  var x4='juan';
  if (isFinite(x4))  //false
    document.write('x4 tiene un valor finito que es el '+x4);
  else
    document.write('x4 no tiene un valor finito que es el '+x4);

</script>
</body>
</html>
El primer if donde verificamos si tiene un valor finito la variable x1 se verifica verdadero:
  var x1=120;
  if (isFinite(x1)) //true
    document.write('x1 tiene un valor finito que es el '+x1);
  else
    document.write('x1 no tiene un valor finito que es el '+x1);
El segundo if se verifica falso donde controlamos el valor almacenado en la variable x2 (tener en cuenta que en JavaScript el valor máximo a almacenar es 1.7976931348623157e+308), la variable almacena el valor Infinity:
  var x2=10e399;
  if (isFinite(x2)) //false
    document.write('x2 tiene un valor finito que es el '+x2);
  else
    document.write('x2 no tiene un valor finito que es el '+x2);
De forma similar si almacenamos un valor negativo que supera la capacidad de JavaScript en la variable se almacena -Infinity:
  var x3=-10e399;
  if (isFinite(x3))  //false
    document.write('x3 tiene un valor finito que es el '+x3);
  else
    document.write('x3 no tiene un valor finito que es el '+x3);
Por último si almacenamos un valor no numérico como un string la función isFinite retorna false:
  var x4='juan';
  if (isFinite(x4))  //false
    document.write('x4 tiene un valor finito que es el '+x4);
  else
    document.write('x4 no tiene un valor finito que es el '+x4);
Para conocer el máximo y mínimo valor que puede almacenar una variable numérica podemos consultar las constantes MIN_VALUE y MAX_VALUE de la clase Number:
<html>
<head>
</head>
<body>

<script type="text/javascript">
  document.write(Number.MIN_VALUE);  // 5e-324
  document.write('<br>');
  document.write(Number.MAX_VALUE);  // 1.7976931348623157e+308
</script>

</body>
</html>
Problema
Mostrar por pantalla el valor 10 elevado a la 1,2,3 etc. hasta que se genere un valor infinito.
<html>
<head>
</head>
<body>
<script type="text/javascript">
  for(var x=1; ;x++)
  {
    var resu=Math.pow(10,x);
    if (isFinite(resu))
      document.write('10 elevado a la '+x+' es '+resu+'<br>');
    else
      break;
  }
</script>
</body>
</html>
Disponemos un for sin condición (con esto hace que para finalizar el mismo debemos llamar al comando break dentro del for cuando se genere un valor infinito, mediante el método pow de la clase Math obtenemos el valor 10 elevado a x (siendo x el contador del for)
Cuando se almacena un valor infinio en resu el if se vefifica falso y se ejecuta el break del else:
  for(var x=1; ;x++)
  {
    var resu=Math.pow(10,x);
    if (isFinite(resu))
      document.write('10 elevado a la '+x+' es '+resu+'<br>');
    else
      break;
  }
Por pantalla obtenemos la lista de 10 elevado a la 1,2,3,4 etc.:
10 elevado a la 1 es 10
10 elevado a la 2 es 100
10 elevado a la 3 es 1000
10 elevado a la 4 es 10000
10 elevado a la 5 es 100000 
.... 

Javascript Parte LXXIII

La función global isNaN (is Not a Number) verifica si el valor que le pasamos es un número válido y podemos estar seguros de operar con dicho valor. Esta función puede ser empleada inmediatamente luego de llamar a las funciones parseInt y parseFloat.
Con un pequeño ejemplo podemos ver los valores que nos retorna la función isNaN si le pasamos variables con un valor entero, float, un string con caracteres numéricos y un string con caracteres alfabéticos:



  var x=10;
  if (isNaN(x))  //false
    alert('no es un número');
  var z=10.5;
  if (isNaN(z))  //false
    alert('no es un número');
  var edad='77';
  if (isNaN(edad))  //false
    alert('no es un número');
  var nom='juan';
  if (isNaN(nom))  //true
    alert('no es un número:'+nom);
Problema
Realizar la carga de dos valores enteros por teclado utilizando la función prompt. Calcular la suma previo controlar que los dos valores sean de tipo numérico.
<html>
<head>
</head>
<body>
<script type="text/javascript">
  var x1,x2,suma;
  x1=prompt('Ingrese el primer valor:','');
  x2=prompt('Ingrese el segundo valor:','');
  x1=parseInt(x1);
  x2=parseInt(x2);
  if (isNaN(x1) || isNaN(x2))
  {
    document.write('Al menos uno de los dos valores ingresados no es numérico.');
  }
  else
  {
    suma=x1+x2;
    document.write('La suma de los dos valores es:'+suma);
  }
</script>
</body>
</html>
Luego de cargar los dos valores por teclado procedemos a convertirlos a tipo entero:
  x1=prompt('Ingrese el primer valor:','');
  x2=prompt('Ingrese el segundo valor:','');
  x1=parseInt(x1);
  x2=parseInt(x2);
Mediante un if verificamos si alguno de los dos valores no es un número:
  if (isNaN(x1) || isNaN(x2))
  {
    document.write('Al menos uno de los dos valores ingresados no es numérico.');
  }

Javascript Parte LXXII

Una expresión regular es una técnica que nos permite identificar si un string coincide con un patrón determinado. Un ejemplo clásico es determinar si un email está correctamente tipeado (sabemos que comienza con uno o más caracteres alfanuméricos, luego el carácter @ seguido de uno o más caracteres alfanuméricos, luego el carácter '.' y finalmente otros caracteres alfabéticos)
Sin conocer las expresiones regulares se pueden resolver estos tipos de problemas mediante una serie de if que procesan partes del string para comprobar si cumplen en conjunto todas las reglas que necesitamos validar, pero con las expresiones regulares podemos resolver este tipo de problemas con una sintaxis mucho más compacta.
Existe toda una serie de reglas para crear las expresiones regulares que iremos viendo.
El lenguaje JavaScript administra las expresiones regulares mediante el objeto RegExp:
Problema
Validar si se ingresa un valor entero con exactamente tres dígitos.
<html>
<head>
</head>
<body>

<script type="text/javascript">
  var valor=prompt('Ingrese un numero entero positivo de 3 dígitos','');
  var patron=new RegExp('^[0-9]{3}$');
  if (patron.test(valor))
    alert('Se ingresó un valor entero positivo de 3 dígitos');
  else
    alert('No se ingresó un valor entero positivo de 3 dígitos');
</script>

</body>
</html>
En este primer paso no nos importa la sintaxis dispuesta en el string que le pasamos al constructor del objeto RegExp, sino ver la sintaxis de JavaScript para crear un objeto de RegExp y seguidamente como llamamos al método test que retorna si el string 'valor' contrastado con la expresión regular definida en el objeto 'patron' verifica verdadero o falso:
  var patron=new RegExp('^[0-9]{3}$');
  if (patron.test(valor))
    alert('Se ingresó un valor entero positivo de 3 dígitos');
  else
    alert('No se ingresó un valor entero positivo de 3 dígitos');
Veremos luego que para definir expresiones regulares intervienen una serie de caracteres ^ $. * +? =! : | \ / () [] {} que tienen un significado especial en la definición del lenguaje de expresiones regulares, estos tipos de caracteres suelen llamarse metacaracteres.
El mismo problema se puede expresar utilizando una sintaxis distinta para la creación de la expresión regular (esta otra sintaxis es muy utilizada, pero en el fondo el interprete de JavaScript crea un objeto de tipo RegExp):
<html>
<head>
</head>
<body>

<script type="text/javascript">
  var valor=prompt('Ingrese un numero entero positivo de 3 dígitos','');
  var patron=/^[0-9]{3}$/;
  if (patron.test(valor))
    alert('Se ingresó un valor entero positivo de 3 dígitos');
  else
    alert('No se ingresó un valor entero positivo de 3 dígitos');
</script>

</body>
</html>
Como podemos ver al definir la variable patron le asignamos una cadena encerrada entre los caracteres '/' (recordar que estamos creando un objeto de tipo RegExp):
  var patron=/^[0-9]{3}$/;
Problema
Ingresar una oración por teclado y luego imprimir un mensaje si la oración ingresada contiene la palabra 'hora'
<html>
<head>
</head>
<body>

<script type="text/javascript">
  var oracion=prompt('Ingrese una oración','');
  var patron=/hora/;
  if (patron.test(oracion))
    alert('La oración ingresada contiene la palabra \'hora\'');
  else
    alert('La oración ingresada no contiene la palabra \'hora\'');
</script>

</body>
</html>
Es muy posible que este primer problema convenga utilizar el método indexOf del objeto string pero para introducir el concepto de expresiones regulares es lo más sencillo. Estamos declarando la expresión regular:
  var patron=/hora/;
Con esta definición especificamos que el patrón a comparar son los caracteres 'hora'. Luego al llamar al método test donde le pasamos el string a comparar verifica si el patrón 'hora' está contenido en alguna posición del string 'oración'.
El método test se verifica verdadero si ingresamos las siguientes oraciones:
Es hora de partir.
hora de comer.
Pasó muchas horas corriendo.
Ahora tenemos ganas de correr.
Se verifica falso si ingresamos la siguiente oración:
El niño ora.
Hora de comer.

Javascript Parte LXXI

El operador == primero hace la conversión a un mismo tipo de dato para verificar si son iguales, en cambio el operador === llamado operador de igualdad estricta compara los valores sin hacer conversiones. Esto hace que cuando utilizamos el operador === retorne siempre false en caso que las variables que comparamos sean de distinto tipo.
El siguiente if se verifica verdadero ya que con el operador == primero se transforman los dos valores al mismo tipo de datos previos a verificar su igualdad:
  var v1='55';
  if (v1==55)
    document.write('son iguales');
En cambio el siguiente if utilizando el operador de igualdad estricta se verifica false ya que son variables o valores de distinto tipo:
  var v1='55';
  if (v1===55)
    document.write('son iguales');
Los operadores != y !== son los opuestos de == y ===.
El operador != retorna true si son distintos previo conversión a un mismo tipo de dato y el operador !== retorna true si los valores son distintos sin hacer una conversión previa, teniendo en cuenta que para tipos de datos distintos es true el valor retornado.
El siguiente if se verifica false:
  var v1='55';
  if (v1!=55)
    document.write('son distintos');
En cambio utilizando el operador !== se verifica verdadero ya que son tipos de datos desiguales:
  var v1='55';
  if (v1!==55)
    document.write('son distintos');
El operador de igualdad estricto === analiza los operandos de la siguiente forma:
  • Si los dos valores son de diferente tipo luego el resultado es false.
  • Si los dos valores almacen null luego el resultado es true. Lo mismo si los dos valores almacenan undefined.
  • Si uno de los valores almacena el valor NaN luego la condición se verifica como false.
El operador de igualdad == analiza los operandos de la siguiente forma:
  • Si los dos operandos no son del mismo tipo el operador == primero verifica si uno de los valores es null y el otro undefined luego retorna true, si uno es un número y el otro un string convierte a string el número y luego compara, si uno de los valores es true convierte este a 1 y luego compara, si uno de los valores es false convierte este a 0 (cero) y luego compara.
Algunas comparaciones:
  if (true==1)  //verdadero
  if (true===1)  //falso
  if (false==0)  //verdadero
  if (false===0)  //falso

Javascript Parte LXX

Todo formulario se le puede capturar el evento submit que se dispara previo a enviar los datos del formulario al servidor.
Uno de los usos más extendidos es la de validar los datos ingresados al formulario y abortar el envío de los mismos al servidos (con esto liberamos sobrecargas del servidor)
El evento submit se dispara cuando presionamos un botón de tipo type="submit".
Para probar el funcionamiento del evento submit implementaremos un formulario que solicita la carga de una clave y la repetición de la misma. Luego cuando se presione un botón de tipo "submit" verificaremos que las dos claves ingresadas sean iguales.
<!doctype html>
<html>
<head>
<title></title>

<script type="text/javascript">

    window.addEventListener('load', inicio, false);

    function inicio() {
        document.getElementById("formulario1").addEventListener('submit', validar, false);
    }

    function validar(evt) {
        var cla1 = document.getElementById("clave1").value;
        var cla2 = document.getElementById("clave2").value;
        if (cla1!=cla2) {
            alert('Las claves ingresadas son distintas');
            evt.preventDefault();
        }
    }

</script>

</head>
<body>

<form method="post" action="procesar.php" id="formulario1">
Ingrese clave:
<input type="password" id="clave1" name="clave1" size="20" required>
<br>
Repita clave:
<input type="password" id="clave2" name="clave2" size="20" required>
<br>
<input type="submit" id="confirmar" name="confirmar" value="Confirmar">
</form>

</body>
</html>
Tengamos en cuenta que la primer línea indica que se trata de una página de HTML5:
<!doctype html>
Definimos un formulario que solicita la carga de dos claves y un botón submit para enviar los datos al servidor:
<form method="post" action="procesar.php" id="formulario1">
Ingrese clave:
<input type="password" id="clave1" name="clave1" size="20" required>
<br>
Repita clave:
<input type="password" id="clave2" name="clave2" size="20" required>
<br>
<input type="submit" id="confirmar" name="confirmar" value="Confirmar">
</form>
Registramos el evento load de la página indicando que se ejecute la función inicio donde registramos el evento submit del formulario:
    window.addEventListener('load', inicio, false);

    function inicio() {
        document.getElementById("formulario1").addEventListener('submit', validar, false);
    }
La función validar extrae los contenidos de los dos "password" y verificamos si tienen string distintos en cuyo caso llamando al método preventDefault del objeto que llega como parámetro lo cual previene que los datos se envíen al servidor:
    function validar(evt) {
        var cla1 = document.getElementById("clave1").value;
        var cla2 = document.getElementById("clave2").value;
        if (cla1!=cla2) {
            alert('Las claves ingresadas son distintas');
            evt.preventDefault();
        }
    }

Javascript Parte LXIX

Hasta ahora siempre hemos asociado una función distinta para procesar los eventos de distintos elementos HTML. Pero veremos que está permitido asociar una único función a varios eventos de distintos objetos.
Debemos definir un parámetro en la función a implementar que llega la referencia del objeto que emitió el evento.
Implementaremos un panel con un conjunto de botones que nos permitan ingresar un valor numérico presionando botones.
Asociaremos el click de cada botón con una única función.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>


<script type="text/javascript">

    window.addEventListener('load', inicio, false);

    function inicio() {
        for (var x = 0; x <= 9; x++) {
            document.getElementById('boton' + x).addEventListener('click', presion, false);
        }
    }

    function presion(evt) {
        document.getElementById('resultado').innerHTML =
            document.getElementById('resultado').innerHTML + evt.target.value;
    }

</script>

<style>
  .boton{
    width:50px;
    height:50px;
  }
  #resultado {
    font-size:40px;
  }
</style>

</head>
<body>


<input type="button" id="boton0" name="boton0" value="0" class="boton">
<input type="button" id="boton1" name="boton1" value="1" class="boton">
<input type="button" id="boton2" name="boton2" value="2" class="boton">
<input type="button" id="boton3" name="boton3" value="3" class="boton">
<input type="button" id="boton4" name="boton4" value="4" class="boton">
<input type="button" id="boton5" name="boton5" value="5" class="boton">
<input type="button" id="boton6" name="boton6" value="6" class="boton">
<input type="button" id="boton7" name="boton7" value="7" class="boton">
<input type="button" id="boton8" name="boton8" value="8" class="boton">
<input type="button" id="boton9" name="boton9" value="9" class="boton">
<br>
<div id="resultado"></div>

</body>
</html>

En el body definimos 10 botones y un div donde mostraremos todos los números ingresados.
<input type="button" id="boton0" name="boton0" value="0" class="boton">
<input type="button" id="boton1" name="boton1" value="1" class="boton">
<input type="button" id="boton2" name="boton2" value="2" class="boton">
<input type="button" id="boton3" name="boton3" value="3" class="boton">
<input type="button" id="boton4" name="boton4" value="4" class="boton">
<input type="button" id="boton5" name="boton5" value="5" class="boton">
<input type="button" id="boton6" name="boton6" value="6" class="boton">
<input type="button" id="boton7" name="boton7" value="7" class="boton">
<input type="button" id="boton8" name="boton8" value="8" class="boton">
<input type="button" id="boton9" name="boton9" value="9" class="boton">
<br>
<div id="resultado"></div>
En el método inicio asociamos los diez botones con la función presion y para reducir el código disponemos un for que se repita 10 veces y llamamos en la misma al método addEventListener (debemos ir obteniendo el id del botón concatenando 'boton' y el contador del for):
    function inicio() {
        for (var x = 0; x <= 9; x++) {
            document.getElementById('boton' + x).addEventListener('click', presion, false);
        }
    }
Lo nuevo aparece en la función presion:
    function presion(evt) {
        document.getElementById('resultado').innerHTML =
            document.getElementById('resultado').innerHTML + evt.target.value;
    }
La función presion tiene un parámetro llamado evt (podemos darle cualquier nombre) y el mismo es un objeto que tiene las siguientes propiedades:
target: Referencia del objeto que generó el evento (en nuestro ejemplo alguno de los 10 botones)
type: El nombre del evento (en nuestro caso click)
button: El botón del mouse presionado (0 = izquierdo, 1 = medio, 2 = derecho)
keyCode: El caracter del teclado presionado (en caso que corresponda)
shiftKey: true o false en caso de estar presionada esta tecla.
Como en este problema debemos ir concatenando el número presionado procedemos a obtener la referencia del div y asignarle el valor actual más la propiedad value del botón presionado:
        document.getElementById('resultado').innerHTML =
            document.getElementById('resultado').innerHTML + evt.target.value;

Javascript Parte LXVIII

El evento focus se dispara cuando se activa el control o toma foco y el evento blur se dispara cuando pierde el foco el control. Podemos capturar el evento focus y blur de un control de tipo text, textarea, button, checkbox, file, password, radio, reset y submit.
Problema
Confeccionar un formulario que muestre dos controles de tipo text. El que está con foco mostrar su texto de color rojo y aquel que no está seleccionado el texto se debe mostrar de color negro.

<html>
<head>

<script type="text/javascript">

  addEventListener('load',inicio,false);

  function inicio()
  {
    document.getElementById('text1').addEventListener('focus',tomarfoco1,false);
    document.getElementById('text2').addEventListener('focus',tomarfoco2,false);
    document.getElementById('text1').addEventListener('blur',perderfoco1,false);
    document.getElementById('text2').addEventListener('blur',perderfoco2,false);
  }

  function tomarfoco1()
  {
    document.getElementById('text1').style.color='#ff0000';
  }

  function tomarfoco2()
  {
    document.getElementById('text2').style.color='#ff0000';
  }

  function perderfoco1()
  {
    document.getElementById('text1').style.color='#000000';
  }

  function perderfoco2()
  {
    document.getElementById('text2').style.color='#000000';
  }

</script>

</head>
<body>

<input type="text" id="text1" name="text1" size="30">
<br>
<input type="text" id="text2" name="text2" size="30">

</body>
</html>
En la función inicio registramos los evento fucus y blur para los dos controles text:
  function inicio()
  {
    document.getElementById('text1').addEventListener('focus',tomarfoco1,false);
    document.getElementById('text2').addEventListener('focus',tomarfoco2,false);
    document.getElementById('text1').addEventListener('blur',perderfoco1,false);
    document.getElementById('text2').addEventListener('blur',perderfoco2,false);
  }
En los métodos tomarfoco1 y tomarfoco2 activamos el color rojo para el texto del control text:
  function tomarfoco1()
  {
    document.getElementById('text1').style.color='#ff0000';
  }

  function tomarfoco2()
  {
    document.getElementById('text2').style.color='#ff0000';
  }
En los métodos perderfoco1 y perderfoco2 procedemos a activar el color negro para los controles text:
  function perderfoco1()
  {
    document.getElementById('text1').style.color='#000000';
  }

  function perderfoco2()
  {
    document.getElementById('text2').style.color='#000000';
  }

Javascript Parte LXVII

El evento change se lo puede asociar a distintos elementos de formularios HTML y su comportamiento depende de cada uno.
Cuando asociamos el evento change a un control de tipo checkbox el mismo se dispara inmediatamente después que lo chequeamos o sacamos la selección. Para los controles de tipo radio también se dispara luego que cambia el estado de selección del mismo.
Para los controles select se dispara el evento change cuando cambiamos el item seleccionado.
Para los controles text y textarea se dispara cuando pierde el foco del control (porque seleccionamos otro control) y hemos cambiando el contenido del mismo.
Problema
Implementaremos una aplicación que muestre un alert cada vez que sucede el evento change para los controles checkbox, radio, select, text y textarea.
<html>
<head>

<script type="text/javascript">

  addEventListener('load',inicio,false);

  function inicio()
  {
    document.getElementById('checkbox1').addEventListener('change',cambiocheckbox,false);
    document.getElementById('radioa').addEventListener('change',cambioradio,false);
    document.getElementById('radiob').addEventListener('change',cambioradio,false);
    document.getElementById('radioc').addEventListener('change',cambioradio,false);
    document.getElementById('select1').addEventListener('change',cambioselect,false);
    document.getElementById('text1').addEventListener('change',cambiotext,false);
    document.getElementById('textarea1').addEventListener('change',cambiotextarea,false);
  }

  function cambiocheckbox()
  {
   alert(document.getElementById('checkbox1').checked);
  }

  function cambioradio()
  {
    alert(document.getElementById('radioa').checked+' '+
          document.getElementById('radiob').checked+' '+
          document.getElementById('radioc').checked);
  }

  function cambioselect()
  {
    alert(document.getElementById('select1').value);
  }

  function cambiotext()
  {
    alert(document.getElementById('text1').value);
  }

  function cambiotextarea()
  {
    alert(document.getElementById('textarea1').value);
  }

</script>

</head>
<body>
Evento change del checkbox:
<input type="checkbox" id="checkbox1" name="checkbox1" checked>
<br>
Evento change del radio:<br>
<input type="radio" name="radio1" id="radioa"><br>
<input type="radio" name="radio1" id="radiob"><br>
<input type="radio" name="radio1" id="radioc"><br>
Evento change del select:
<select name="select1" id="select1">
  <option value="argentina">Argentina</option>
  <option value="chile">Chile</option>
  <option value="uruguay">Uruguay</option>
  <option value="paraguay">Paraguay</option>
  <option value="bolivia">Bolivia</option>
</select>
<br>
<input type="text" name="text1" id="text1">
<br>
<textarea name="text1" id="textarea1" rows="6" cols="80"></textarea>
<br>
</body>
</html>
Creamos una serie de controles de formulario HTML en el body de la página:
Evento change del checkbox:
<input type="checkbox" id="checkbox1" name="checkbox1" checked>
<br>
Evento change del radio:<br>
<input type="radio" name="radio1" id="radioa"><br>
<input type="radio" name="radio1" id="radiob"><br>
<input type="radio" name="radio1" id="radioc"><br>
Evento change del select:
<select name="select1" id="select1">
  <option value="argentina">Argentina</option>
  <option value="chile">Chile</option>
  <option value="uruguay">Uruguay</option>
  <option value="paraguay">Paraguay</option>
  <option value="bolivia">Bolivia</option>
</select>
<br>
<input type="text" name="text1" id="text1">
<br>
<textarea name="text1" id="textarea1" rows="6" cols="80"></textarea>
<br>
En la función inicio asociamos a todos los controles para el evento change un método:
  function inicio()
  {
    document.getElementById('checkbox1').addEventListener('change',cambiocheckbox,false);
    document.getElementById('radioa').addEventListener('change',cambioradio,false);
    document.getElementById('radiob').addEventListener('change',cambioradio,false);
    document.getElementById('radioc').addEventListener('change',cambioradio,false);
    document.getElementById('select1').addEventListener('change',cambioselect,false);
    document.getElementById('text1').addEventListener('change',cambiotext,false);
    document.getElementById('textarea1').addEventListener('change',cambiotextarea,false);
  }
La función cambiocheckbox se dispara cada vez que cambiamos el estado del checkbox (tanto cuando lo seleccionamos como cuando lo deseleccionamos):
  function cambiocheckbox()
  {
   alert(document.getElementById('checkbox1').checked);
  }
La función cambioradio se dispara cada vez que seleccionamos alguno de los tres radio:
  function cambioradio()
  {
    alert(document.getElementById('radioa').checked+' '+
          document.getElementById('radiob').checked+' '+
          document.getElementById('radioc').checked);
  }
La función cambioselect se dispara cuando cambiamos de item del control select:
  function cambioselect()
  {
    alert(document.getElementById('select1').value);
  }
La función cambiotext y cambiotextarea se ejecuta cuando perdemos el foco del control y hemos producido un cambio en su contenido (agregado o borrado caracteres de su interior):
  function cambiotext()
  {
    alert(document.getElementById('text1').value);
  }

  function cambiotextarea()
  {
    alert(document.getElementById('textarea1').value);
  }