31 de octubre de 2017

JavaScript - BOM (Modelo de Objetos del Navegador)

BOM es el acrónimo de Browser Object Model (Modelo de Objetos del Navegador). Este modelo permite a JS comunicarse con el navegador que ha cargado la página.

No hay un estándar oficial para BOM, aunque los navegadores modernos implementan casi los mismos métodos y propiedades.

Nos ofrece una serie de objetos al nivel de document y superior para poder manipular parecido al siguiente árbol:


Window

En el nivel más alto tenemos al objeto window que implementan todos los navegadores. Este objeto representa una ventana/pestaña abierta del navegador (y otra por cada <iframe> que contenga).

Todos los objetos, funciones y variable globales pasan a ser miembros de window automáticamente. El objeto document del HTML DOM es una propiedad de window: window.document.

Para utilizar un miembro de window se puede obviar ésta palabra, pues es el acceso por defecto (como si hubiera un import de window.*). De hecho los métodos alert() y prompt() ya utilizados son métodos de window y los hemos llamado de esta forma.

Con window podemos abrir una nueva ventana, cerrarla, moverla, hacer scrolls, cambiar el tamaño, pasar/quitar el foco, etc...

Obtendremos un objeto window cuando abramos una dirección con window.open(url, nombre, specs, reemplazar). Si queremos una referencia a la ventana actual podremos obtenerla con self y comparándola con top podemos trabajar con los iframes.

Una utilidad importante de window es que se pueden almacenar pares "clave/valor" para personalizar la experiencia del usuario con la propiedad window.sessionStorage para una sesión o window.localStorage para obtener persistencia después de cerrar el navegador.

Window permite ejecutar código con un temporizador (en milisegundos) usando setInterval(funcion, intervalo) para llamadas separadas por el intervalo o setTimeout(func, interv) para ejecutarse una vez trascurrido un tiempo. Estos temporizadores seguirán ejecutándose hasta que no se reseteen con clearInterval(id) o clearTimeout(id) respectivamente. El id que hay que usar con estas últimas es el identificador que devuelven los métodos setInterval y setTimeout.

Hay una serie de propiedades que nos dan acceso a objetos importantes del navegador y que se detallan más abajo.

Navigator

La propiedad navigator proporciona el objeto que contiene la información del navegador: nombre de la aplicación, versión, plataforma, lenguaje, localización, etc...

Screen

La propiedad screen proporciona el objeto que contiene información de la pantalla del usuario: alto, ancho, profundidad de color y resolución.

History

La propiedad history proporciona el objeto que contiene las URLs visitadas por el usuario dentro del objeto window al que pertenece. Permite moverse hacia delante y atrás o ir directamente a una URL visitada.

Location

La propiedad location proporciona el objeto que contiene información acerca de la URL actual: nombre del host, ruta, puerto, hash, query string, etc...

Práctica js-bom-1

Práctica js-bom-2

Práctica js-bom-3

26 de octubre de 2017

JavaScript - DOM (Modelo de Objetos del Documento)

Cuando una página web es cargada, el navegador crea un Document Object Model (DOM) = Modelo de Objetos del Documento.
Se suele conocer también como árbol DOM, ya que todos los nodos se mapean descendiendo escalonadamente del nodo raíz (document)


DOM es un standard del W3C define una interfaz de programación independiente del lenguaje y plataforma que permite acceder y modificar cada uno de los nodos que lo forman (manejar el contenido, estructura y estilo de un documento) Se divide en múltiples interfaces, pero nos vamos a centrar en HTML DOM.

Mediante lenguajes como Java, XPath y ECMAScript (JavaScript), entre otros, se utiliza el HTML DOM para manipular los elementos HTML como objetos con sus métodos, propiedades y eventos.
NOTA: Ejemplos famosos de estos son el método getElementById(id), la propiedad innerHTML o el evento onclick

En DOM todo es un nodo (tipo Node):
  • El documento es un nodo document
  • Todos los elementos HTML son nodos element (tipo Element)
  • Todos los atributos HTML son nodos attribute (tipo Attr)
  • El texto dentro de elementos HTML son nodos text
  • Los comentarios son nodos comment
Podremos conocer el tipo de nodo que tenemos con la propiedad nodeType.

Node

Los nodos son los elementos sobre los que se contruyen las conexiones del árbol DOM. Pueden tener relación de padre, hijo o hermano:


Básicamente se puede crear un nodo, añadir un nodo a otro en una posición concreta entre el resto de nodos que contiene, eliminar un nodo o reemplazarlo por otro. Veamos un ejemplo:
  1. Creamos un nodo en el documento con document.createElement("div") para crear un nodo elemento con etiqueta div o con document.createTextNode("Mi Texto") para crear un nodo de texto. Estos métodos devuelven los nodos creados.
  2. Si almacenamos las referencias anteriores en las variable "capa" y "texto" respectivamente, podemos añadir un nodo a un elemento creado para que pase a ser su último hijo con capa.appendChild(texto). Si queremos colocarlo en otra posición usariamos capa.insertBefore(otroTexto, texto).
  3. De la misma forma que añadimos podemos eliminar un nodo hijo con el método capa.removeChild(texto), o reemplazarlo con otro de sus hijos capa.replaceChild(document.createTextNode("Nuevo texto"), texto).
El ejemplo completo sería
//Creamos un nodo en el documento
var capa = document.createElement("div");
var texto = document.createTextNode("Mi Texto");

//Añadimos un nodo a un elemento
capa.appendChild(texto); //pasa a ser su último hijo (lastChild)
//Si queremos colocarlo en otra posición
capa.insertBefore(texto, otroNodo); //colocado delante de otroNodo(nextSibling)

//De la misma forma que añadimos podemos eliminar un nodo hijo
capa.removeChild(texto);
//O reemplazarlo con otro de sus hijos
capa.replaceChild(document.createTextNode("Nuevo texto"), texto);
Con estas operaciones podemos modificar todo el contenido de un documento HTML, pero hay que tener cuidado con los métodos que se usan ya que hemos utilizado nodos de distintos tipos (document, element y text), pero tienen diferencias que hay que tener en cuenta (element puede tener hijos pero text o attribute no) y al no ser un lenguaje tipado debemos controlarlo nosotros.

Document

Un documento HTML que se carga en el navegador se convierte en un objeto document. Éste objeto es el nodo raíz y propietario de los otros nodos.
NOTA: En la entrada anterior facilitaba una guía de consulta rápida para hacernos una idea de los métodos y propiedades con los que cuenta cada tipo en JS. También nos puede servir el tema HTML DOM Document Object de w3school.

Los más importantes para acceder al resto de nodos son:
Una diferencia importante entre ellos es si queremos conseguir un único nodo o una lista de nodos (HTML Collection o NodeList)

Merece la pena mencionar una vez más el método write(mensaje), ya utilizado antes, que es una de las formas de producir salidas que podemos apreciar. Pero hay muchos más que nos permiten acceder a la URL, título, codificación, scripts, cookies, formularios, enlaces, imágenes, quién lo cargó (referrer), etc...

Como dijimos antes, hay que tener cuidado con no utilizar métodos que document hereda de Node y que no tiene sentido usar como los atributos o el nodo padre, porque document no tiene valores para ellos.

Element

Cada componente HTML forma un nodo element. Puede contener y ser hijo de otros elementos como vimos antes, pero además puede poseer atributos (Attr) y estilo que no posee document.
  • Para obtener un mapa con todos los atributos que posee un elemento se usa la propiedad element.attributes que devuelve un NamedNodeMap. Los valores se pueden obtener por el índice con item(indice) o por nombre de atributo con getNamedItem("nombre").
  • Para obtener el estilo se usará la propiedad element.style, que nos permitirá leer y establecer cada propiedad CSS. DOM Style es una propiedad de sólo lectura, permite cambiar cada atributo de ella (como backgroundColor por ejemplo) pero no asignar un atributo estilo. Si se quiere manipular el estilo completo, se recomienda hacerlo por su texto CSS usando la propiedad cssText.
  • Podemos acceder al id del elemento con element.id
  • Por útimo es habitual modificar el contenido de un elemento usando su propiedad element.innerHTML que contiene el valor de todo el contenido HTML del elemento. Sin embargo se recomienda modificar el contenido alterando los nodos DOM por rendimiento.
Hay muchos más métodos y propiedades para acceder al tamaño del elemento, posición, eventos, etc... Lo mejor es ir practicando con ellos para conocerlos todos.
Realiza estos ejercicios para practicar:


Práctica js-dom-1

Práctica js-dom-2

Práctica js-dom-3

Práctica js-dom-4

18 de octubre de 2017

JavaScript - Sintaxis

La sintaxis de JS es muy parecida a la de Java, pero tiene sus particularidades que describiremos a continuación. Esta entrada no pretende ser extensiva y sólo se mencionarán las diferencias o métodos más básicos (y antiguos).

Generalidades

  • No se tiene en cuenta los espacios en blanco y nuevas líneas (como en HTML)
  • Es Case sensitive (distingue mayúsculas y minúsculas: miVariable ≠ mivariable)
  • Terminar las sentencias con ';' (buena práctica)
  • Comentarios empiezan con '//' o un bloque entre '/* ... */' (como Java y CSS). Es importante resaltar que esto sólo sirve en bloques JS (como el código encerrado entre etiquetas <script> o nuestro fichero .js), no en el resto del documento HTML en el que pudiéramos tener código incrustado.

Variables

No se define el tipo de variables (mejor se usa palabra clave 'var')
Se puede usar letras, números, '$' y '_', pero no puede empezar un por número
var miVariable = 0;
var mivariable = "1";
miVariable == mivariable; //false

Tipos predefinidos

Numérico (enteros y reales)
  • Enteros: en formatos decimal (n10), hexadecimal (0xn16) y octal (0n8) => NO escribir números con un cero al principio o pueden ser interpretados como en octal
  • Reales: parte entera y parte decimal: 25.478, 2.3e-45, -3e3
Texto (literal)
  • Entre comillas simples o dobles. Si pueden cerrar dentro con comillas distintas a las que las rodean.
  • Uso de carácter de escape '\' + carácter, código ASCII en octal o hexadecimal
Booleano
  • Sólo dos valores: true / false

Objetos

JS tiene en la actualidad una serie de tipos de objetos genéricos y un gran número de métodos que han ido creciendo según se van desarrollando nuevas funcionalidades. Lo mejor es hacerse con una guía de referencia rápida (cheatsheet) en papel para su consulta hasta que estemos familiarizados con todas ellas. Puedes descargarte la referencia de @Manz en github. Tiene más sobre HTML y CSS. Si te son útiles piensa en colaborar con un donativo para que se sienta estimulado a seguir ayudando. Si prefieres una referencia en línea, es muy práctica la referencia de w3schools que podría tomarse como nuestra Biblia en este asunto.

Arrays
Se definen como una enumeración de elementos de cualquier tipo y valor, separados por comas y encerrados entre corchetes:
var miArray = [ "Uno", 2, true ]; //Texto, número y booleano
Se puede acceder a una posición usando su índice (en base cero): miArray[0]
Se puede conocer su número de elementos con su propiedad length.

Tienen varios métodos para trabajar con ellos:
  1. slice(): devuelve una copia del array
  2. concat(): devuelve la unión dos arrays
  3. join(separador)
    1. función "contraria" a split()
    2. une los elementos de un array para formar una cadena de texto separados por el carácter pasado como argumento
  4. pop(): elimina el último elemento del array y lo devuelve
  5. push(valor): añade un elemento al final del array
  6. shift() / unshift(valor): lo mismo que los dos anteriores pero con el principio del array
  7. reverse(): coloca los elementos en orden inverso
Cadena
Es cualquier texto entre comillas.
Aunque se pueda usar como un objeto de tipo String es mejor evitarlo. Ejemplo, no usar: var cadena = new String('Hola Mundo');

Para comparar cadenas hay que tener en cuenta que:
Tiene los típicos métodos para separar, unir, recortar, pasar a mayúsculas/minúsculas, comparar el comienzo, el fin, etc... se puede ver fácilmente en la referencia.

Operadores

Son los típicos que podemos encontrar en Java, C++, etc...:
  • Asignación: var miVariable = 0;
  • Aritméticos: +, -, *, / y % (resto de la división). Se puede combinar con el de asignación:
    miVariable += 3;
    // es igual que
    miVariable = miVariable + 3;
    
  • Lógicos: && (AND), || (OR) y ! (negación)
  • Comparación: <, >, <=, >=, ==, !=. También existe === que comparar valor y tipo de objetos.

Estructuras de Control

De igual forma tenemos las estructuras habituales de Java:

Sentencia condicional if:
if (condicion){...}
else {...}

Bucle for y for...in(lo usamos cuando sabemos el número de elementos a recorrer):
for (inicializacion; condicion; actualizacion) {...}
// O también
for (indice in coleccion) {...}

Ojo, ver documento "for in" de MDN al respecto (itera sobre las propiedades del objeto) para recorrer los objetos de un iterable se usa for...of:
for (elemento of coleccion) {...} //Experimental

Bucle while (cuando no sabemos el número, sólo la condición):
while (condicion) {
  ...
}

Bucle do...while (igual que antes pero al menos tenemos que hacerlo una vez):
do {
  ...
} while (condicion);

Sentencia switch:
switch (valor) {

  case valor1:
    ...
    break;
    ...
  default:
    ...
    break;
}


Interrupción de bucles:
  • continue: interrumpe la ejecución y continua con el siguiente elemento.
  • break: aborta la ejecución del bucle y lo abandona.

Funciones

  • Las funciones encapsulan código JS que realiza una tarea (procedimiento), pueden reutilizarse y pueden devolver un valor.
    function nombreFuncion (parametro1, parametro2, ...) {
      ...
      return resultado;
    }
    
  • Crean un ámbito (scope) propio. Las variables locales se destruyen al abandonar la función.
  • La función se ejecuta cuando se llama con () y los parámetros necesarios en su caso, si no, devuelve la definición de la función (no su resultado)
    var resultado = nombreFuncion;
    // no ejecuta la función, asigna la función ala variable resultado
    resultado = nombreFuncion();
    // ahora sí asignará el resultado porque se ha invocado
    
  • Los parámetros son opcionales, no necesitan encajar perfectamente con una firma como en Java.

Funciones predefinidas
  • eval(expresión): sirve para evaluar una expresión matemática que está en formato texto.
  • isNaN(valor): devuelve 'true' si valor NO es un número válido (Not a Number). Cualquier operación aritmética con NaN resulta en NaN.
  • parseInt(numero, base): transforma el argumento en la base pasada.
  • parseFloat(numeroReal): transforma el argumento en un número en coma flotante.
  • toString(numero): devuelve el número en formato cadena.
  • toFixed(decimales): devuelve el número con el redondeo necesario para las posiciones decimales solicitadas.
  • escape(cadena) / unscape(dirección URL): sirve para transformar caracteres no válidos en formato URL a sus equivalentes y viceversa. Están obsoletas (deprecated)

Realiza estos ejercicios para practicar:

Práctica js-sin-1

Práctica js-sin-2

Práctica js-sin-3

Práctica js-sin-4

Referencias:
Mozilla Developer Network (MDN): Sintaxis
w3schools: Sintaxis
Recomendado: Usa los tutoriales de Mozilla.

17 de octubre de 2017

Javascript - Fundamentos

¿Qué es JavaScript?

JavaScript (JS) es un lenguaje de programación interpretado, dialecto del estándar ECMAScript. Se define como:
  1. Orientado a objetos
  2. Basado en prototipos => No se instancian Clases, clona objetos existentes (prototipos) o código
  3. Imperativo
  4. Débilmente tipado y dinámico (tipo asociado al valor, no a la variables)
Principalmente es utilizado del lado del cliente (client-side) interpretado por un navegador web permitiendo mejoras en la interfaz de usuario y páginas web dinámicas al mismo tiempo que las sentencias van descargándose junto con el código HTML (propósito original).
También se utiliza en aplicaciones externas a la web, por ejemplo en documentos PDF, y aplicaciones de escritorio (mayoritariamente widgets).
Actualmente también se usa del lado del servidor (Server-side JavaScript o SSJS) como en Node.js o Apache Couch DB.

JS NO es Java (las dos marcas pertenecen a Oracle), aunque adopta nombres y convenciones de este lenguaje, tienen semánticas y propósitos diferentes.
JS implementa Document Object Model (DOM) para interactuar con una página web.
Actualmente es ampliamente utilizado para enviar y recibir información del servidor junto con ayuda de otras tecnologías como AJAX.

JS es conocido como el lenguaje de script para la Web, ofreciendo funcionalidades completas al usuario con el resto de componentes habituales que podemos encontrar en cualquier página web:
  1. HTML define el contenido de las páginas
  2. CSS especifica el diseño (layout)
  3. JavaScript programa el comportamiento

¿Cómo se relacionan HTML, CSS y JS?

El código JS se descargará junto con el resto de código de una página web. Hay varias opciones para añadir JS a una página web:
  1. puede incrustarse en un elemento,
  2. definirse en un elemento style en la cabecera o
  3. enlazarse con un archivo JS externo
<!DOCTYPE html>
<html>
<head>
 <script type="text/javascript">
  //Definido en cabecera (Caso 2, Funcionalidad 2a)
  function getTexto() {
    return 'Texto incrustado';
  }
 </script>
 <script type="text/javascript">
  //Llamada al leer la invocacion (Caso 2, Funcionalidad 2b)
  document.write(getTexto() + ' (Caso 2, Funcionalidad 2b)');
 </script>
 <script type="text/javascript"
         src="https://sites.google.com/site/awes0mem4nfiles/codigoJS.js">
  //Referencia a Codigo JS (Caso 3, Funcionalidad 3)
 </script>
</head>
<body>
 <noscript> No tengo activado JS (Funcionalidad 1) </noscript>
 <script type="text/javascript">
  //Llamada al leer la invocacion (Caso 1 y 3, Funcionalidad 4)
  document.write('<br>' + getTexto() + ' (Caso 1 y 3, Funcionalidad 4)');
 </script>
 <p onclick="alert('JS dentro atributo de elemento')">
  Pincha para ver un mensaje incrustado en un elemento (Caso 1, Funcionalidad 5)
 </p>
 <button type="button" onclick="escribirTextoArchivo()">
  Llama a función en archivo .js (Caso 3, Funcionalidad 6)
 </button>
</body>
</html>
En este fragmento de código podemos ver todas las opciones para usar código JS enumeradas anteriormente (lo importante ahora mismo no es conocer la sintaxis de JS, sólo es una muestra de cómo se introduce y se comporta el código JS).
Este ejemplo implementa las siguientes funcionalidades:
  1. Muestra un mensaje si no se tiene activada la ejecución de JS en el navegador.
  2. Si está activado se añade al documento el texto de la función "getTexto()"
  3. Enlaza un archivo .js externo
  4. Se añade el texto de la función "getTexto()". Ha cambiado porque se ha sobreescrito (override)al enlazarse código JS donde hay una función con el mismo nombre
  5. Añade un párrafo que al recibir el evento "onclick" ejecuta código incrustado en él
  6. Añade un botón que llama a una función con el evento "onclick"
La mejor opción es usar un enlace a un archivo con el código JS, ya que nos facilitará enormemente el mantenimiento (si no habría que retocar cada página con código incrustado y no es una buena idea)
Además podemos utilizar una gran cantidad de librería de terceros que nos proporcionarán muchas funcionalidades enlazándolas de esta forma.

Dejaremos el código declarado en la página para hacer modificaciones que sólo afecten a la página que lo contiene (por ejemplo para crear una nueva función/variable que no se reutilizará, o para modificar una existente pero que debe variar su comportamiento) .

Incrustar código en un elemento nos servirá normalmente para personalizar una llamada (por ejemplo para pasarle un argumento a una función)

Ninguno de los casos tiene una mejora respecto a la conexión de red ya que podemos alojar los scripts externos en nuestro propio servidor (los mismos que sirven el HTML) para no depender de terceros.

En el siguiente artículo veremos la sintaxis básica.
Realiza estos ejercicios para practicar:

Práctica fundamentos 1

Práctica fundamentos 2

Profundiza más en las referencias:

Compárteme

Entradas populares