Javascript: Particularidades del Lenguaje, DOM, Eventos y AJAX
1. Javascript
Javascript
Javier Infante <jabi@irontec.com>
Zamudio :: Bizkaia Enpresa Digitala ::14/12/2009
2. Javascript
Particularidades del Lenguaje
● Incluir Javascript en nuestros documentos HTML
– INCLUSIÓN en (X)HTML:
● Inline en el documento:
<script type="text/javascript">
//<![CDATA[
código....
//]]>
</script>
● Separando contenido de estructura:
<script type="text/javascript"
src="scripts.js"></script>
3. Javascript
Particularidades del Lenguaje
● Tipos de datos:
– var intValue = 1;
– var floatValue = 3.0;
– var sqString = 'This is also a string'; // Objeto tipo String
– var array = [1,2,3]; // Objeto tipo Array
– var obj = {1,2,3};
– var function = new function() {};
● Javascript es un lenguaje con tipado débil.
● Las variables son declaradas con la palabra reservada
“var”, y són válidas en su ámbito de declaración.
– Si no se especifica var, la variable será automáticamente
declarada como global.
4. Javascript
Particularidades del Lenguaje
● Ámbitos de ejecución
– Ámbito global o window
● Por defecto siempre estaremos en el ámbito global
window.
● Cualquier función o variable declarada, será un método o
propiedad del objeto window.
● Algunos métodos/propiedades útiles del objeto window
– window.document
– window.setTimeout(function,milisegundos)
– window.setInterval(function,milisegundos)
– window.alert(mensaje)
– window.prompt(mensaje)
5. Javascript
Particularidades del Lenguaje
– Ámbito de ejecución funcional.
● Al entrar en la ejecución de una función, el ámbito de
ejecución (scope), cambia al entorno de esa función.
Todas las variables definidas dentro de la función, serán
sólo accesibles desde esa función.
– Toda variable no definida, será tomada / seteada en el
ámbito global.
● No confundir el scope (ámbito de las variable) con el
contexto (objeto sobre el que se ejecuta la función).
6. Javascript
Particularidades del Lenguaje
● Referencias
– Una referencia es un puntero a la localización actual de
un objeto.
– Al copiar un objeto, éste se copiará por referencia.
– Dos variables pueden apuntar al mismo objeto. La
modificación de una de ellas, tendrá consecuencias
para el objeto concreto.
– Si una de las variables apuntada a un mismo objeto, es
instanciada (construyendo otro objeto), la referencia se
perderá.
7. Javascript
Particularidades del Lenguaje
● Sobrecarga de funciones y comprobación de tipos
– En el contexto de cada función, tenemos disponible una
variable tipo array que contendrá los argumentos con la que
la función ha sido llamada.
arguments
– Para comprobar el tipo de una función, tenemos dos
posibilidades:
● Operador typeof
– Nos devuelve el tipo de variable (string, objeto, numero,
boolean...)
– Es imposible determinar el tipo de objeto
● Propiedad constructor
– Dado que todas las variables en realidad son objetos,
determina el constructor de cada una.
8. Javascript
Particularidades del Lenguaje
● Tabla comparación typeof – constructor
Variable typeof variable variable.constructor
{idx:'valor'} object Object
['uno','dos'] object Array
function() {} funcion Function
'Hola Mundo' string String
55 number Number
true boolean Boolean
new Objeto() object Objeto
9. Javascript
Particularidades del Lenguaje
● Orientación a Objetos (I)
– Objeto = conjunto de métodos y propiedades
encapsuladas.
– Javascript es completamente orientado a objetos. Es
imposible escribir código Javascript funcional.
– Recordar que siempre estamos bajo el objeto global window.
– Creación de un objeto simple:
var obj = new Object();
obj.propiedad2 = 'cosa';
var obj = {
propiedad2 : 'cosa'
}
10. Javascript
Particularidades del Lenguaje
– No existe el concepto de clases.
– Javascript es un lenguaje orientado a prototipos.
● Creación de un objecto simple a partir de una función
function Vehiculo(marca) {
this.marca = marca;
}
var obj = new Vehiculo();
alert(obj.marca);
alert(obj.constructor == Vehiculo);
11. Javascript
Particularidades del Lenguaje
– Métodos/Propiedades públicos
● Métodos accesibles por cada instancia del objeto en
particular.
● La palabra reservada this, hace referencia al objeto
instanciado en cada momento.
● Éstos deben añadirse a la propiedad prototype de cada
Objeto.
function Vehiculo(marca) {
this.marca = marca;
}
Vehiculo.prototype.getMarca = function (){
return this.marca;
}
12. Javascript
Particularidades del Lenguaje
● Contextos
– En javascript siempre nos encontramos en el ámbito de un
contexto. Es decir, siempre estamos operando bajo el ámbito
de un objeto determinado.
– El contexto por defecto en el que se ejecutan las funciones es
window.
● Salvo en el caso de Métodos Públicos, donde this hará
referencia a cada instancia.
– apply / call
● Dos métodos que nos permiten ejecutar funciones
especificando su contexto de ejecución.
nFuncion.apply(objeto,[array de argumentos]);
nFuncion.call(objeto,arg1,arg2,...);
13. Javascript
Particularidades del Lenguaje
● Closures / Cierres
– Funcionalidad gracias a la cual, una variable del scope
“padre”, estará disponible en el scope hijo, aún cuando
termine la ejecución del hilo padre.
– Permite aislar entornos de ejecuciones concurrentes de
código -sacar nuestro código del ámbito global- sin peligro
de sobreescribir variables.
– Funcionalidad muy útil a la hora de crear listeners para
eventos, timers, etc...
14. Javascript
Particularidades del Lenguaje
● Orientación a Objetos (II)
– Herencia de prototipos.
● Es posible conseguir herencia en la definición de nuevos
objetos.
● Teniendo en cuenta que los métodos públicos son
almacenados en la propiedad “prototype” de cada objeto,
bastará con referenciar esa propiedad a un nuevo objeto de
tipo “padre”, para que los métodos definidos en este
objeto, estén disponibles en el “hijo”.
15. Javascript
Particularidades del Lenguaje
function Padre() {
var metodo2 = function() {}
}
Padre.prototype.metodo = function() {
}
function Hijo() {
}
Hijo.prototype = new Padre();
// Hijo.metodo() e Hijo.metodo2() estarán disponibles en
cualquier instancia de Hijo.
16. Javascript
Particularidades del Lenguaje
● Orientación a Objetos (II)
– Métodos/Propiedades Privados: Declaración de métodos
accesibles solamente desde el ámbito de objeto (mucho ojo a
los ámbitos).
function Vehiculo(marca) {
this.marca = marca; ← prop. público
var arrancado = false; ← prop. privada
function encenderMotor() { ← // SCOPE global
arrancado = true; ← this == window?
}
encenderMotor.call(this); ← llamada
especif. scope
this.arrancar = function() {← acc. publico
encenderMotor.call(this); ← acc.privado
}
}
17. Javascript
Empaquetando código para publicar
● A la hora de poner en producción nuestro código Javascript,
tanto para una web concreta, o para la publicación de un
código de una funcionalidad determinada, tenemos que tener
en cuenta los siguientes aspectos:
– Peso del script: Suele ser el principal cuello de botella en
cuanto a rendimiento de nuestros scripts.
– Ámbito de declaración de nuestros métodos / variables:
Sobre todo si se pretende convivir con otros códigos /
plugins... Es importante “NO PISARSE”.
– Que sea multinavegador (pero esto es otra historia)...
18. Javascript
Empaquetando código para publicar
● Optimizando el peso del script.
– Existen 2 métodos usados globalmente para optimizar el peso
de nuestros scripts:
● JSMin http://www.crockford.com/javascript/jsmin.html
● http://fmarcia.info/jsmin/test.html
● Librería portada a multitud de lenguajes (PHP / Python /
.NET/ etc..), que elimina comentarios, espacios en blanco y
saltos de línea, consiguiendo notables “ahorros” de ancho
de banda.
● Packer http://dean.edwards.name/packer/
● Código super potente y muy complicado, que genera a
partir de nuestro script, otro script autoejecutable (y
comprimido), que dará como resultado nuestro script
inicial.
● Poco adecuado para ficheros pequeños.
19. Javascript
Empaquetando código para publicar
● Limpiando nuestro código
– Sobre todo cuando utilicemos JSMin, nuestro código tiene
que estar correctamente escrito para evitar errores de
interpretación sobre el código comprimido.
– Existe la Librería JSLint para comprobar la “calidad” de
nuestro código.
http://www.jslint.com/
– Errores comunes:
● Cuidado con los operadores de auto incrementar:
var j = i++ +3;
Al comprimir esa línea, nos quedará lo siguiente:
– var j = i+++3; // Sin espacio, lo cual dará un error de
interpretación
– Lo Correcto:
var j = (i++)+3;
20. Javascript
Empaquetando código para publicar
● Punto y coma, después de cada asignación:
var func = function(a,b) {
return a+b;
}; // ← Sin punto y coma funcionará, pero nos dará error si
comprimimos este código.
function sumar(a,b) {
return a+b;
} // ← Aquí no ponemos punto y coma, ya que es la
declaración de una función.
21. Javascript
Empaquetando código para publicar
● Optimizando el peso del script.
– La mayor parte de navegadores serios del mercado, tiene
soporte para descomprimir páginas servidas gzipeadas.
Content-encoding: gzip
– Existen modulos para Apache 2.0 para servir el contenido de
texto gzipeado:
a2enmod deflate
- Simplemente añadiendo estas líneas en el .htaccess (o mejor
aun en el fichero de configuración de apache)
AddOutputFilterByType DEFLATE text/html text/css text/plain
text/xml application/x-javascript
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4.0[678] no-gzip
BrowserMatch bMSIE !no-gzip !gzip-only-text/html
22. Javascript
Empaquetando código para publicar
● Namespacing
– Aunque en Javascript no existe como en otros lenguajes
(como Java, Python o PHP 5.3) la técnica de namespacing.
Ésta técnica permite “encerrar” fragmentos de código, de
manera que variables y funciones globales no se pisen en
interactuación con otras librerías.
– En Javascript, la técnica ideal, es encapsular todas nuestras
variables y funciones en un objeto único.
– Y nunca (salvo en casos excepcionales), utilizar variables
globales.
23. Javascript
Document Object Model
● DOM
– Metodología estándar para representar un documento
XML (aunque existen otras muchas, y posiblemente
más eficientes)
– Implementada en varios lenguajes, fue elegida por el
W3C como estándar para referenciar al documento
HTML.
– El estándar definido, está implementado “parcialmente”
por casi todos los navegadores comerciales.
– Los documentos HTML poseen una estructura hereditaría
representada como una estructura de árbol.
– Conjunto de propiedades y métodos para recorrer
árboles XML (HTML), y examinar o modificar sus
nodos.
24. Javascript
Document Object Model
<html>
<head>
<title>Sample Document</title>
</head>
<body>
<h1>An HTML Document</h2>
<p>This is a <i>simple</i> document.
</body>
</html>
26. Javascript
Document Object Model
● Árbol Web
– Un documento XHTML se compone de un conjunto de
nodos.
– Un nodo es un objeto accesible y modificable.
– Propiedades:
.nodeType
● Propiedad más importante, que nos indica el tipo de nodo
que es:
– 1 || ELEMENT_NODE : Nodo de tipo TAG
– 3 || TEXT_NODE : Nodo de tipo Texto (CUIDADO!)
.attributtes
● Devuelve array con los atributos de un nodo.
27. Javascript
Document Object Model
.nodeName
● Propiedad que devuelve el nombre del tag
.innerHTML
● Devuelve el contenido HTML dentro del tag
.nodeValue
● Devuelve el texto en caso de nodeType == 3
.childNodes
● Devuelve un array con todos los nodos hijos de ese nodo.
28. Javascript
parentNode Document Object Model
previousSibling nextSibling
Nodo
firstChild
lastChild
– Cada nodo poseé 5 punteros (referencias a otros nodos)
que apuntan a sus nodos relacionados
– El acceso a través de puntos, no es muy óptimo.
– Relaciona cada nodo con sus familiares.
29. Javascript
Document Object Model
● window.document
– Propiedad del objeto global window de la que heredan
los métodos los nodos disponibles en el DOM.
document.documentElement
referencia al nodo raiz <html>
document.body
referencia al nodo <body>
– Métodos de window.document
.getElementById(iden)
Devuelve 1 único elemento identificado por el atributo
único “id”;
.getElementsByTagName(“tag”)
Devuelve un array con todos los nodos cuyo tag coincida
con “tag”.
30. Javascript
Document Object Model
● Método de nodo
.createElement()
Crea un nodo de tipo elemento
var oEM = document.createElement(“em”);
.createTextNode()
Crea un nodo de tipo Texto
var oTxt = document.createTextNode(“hola”);
.appendChild()
Inserta un elemento como último hijo de otro
oEM.appendChild(oTxt);
.appendData(data)
Inserta texto dentro de un nodo de texto
oEM.lastChild.appendData(“ ¿Qué tal?”);
.cloneNode
Clona un elemento
var oEM2 = oEM.cloneNode(true);
31. Javascript
.insertBefore() Document Object Model
Inserta un nodo, antes de un nodo hijo espefico.
var o = document.createElement(“em”);
o.appendChild(document.createTextNode(“adios”));
document.getElementById(“p1”).insertBefore(o,documnet.get
ElementById(“s1”));
.removeChild()
Elimina un nodo hijo determinado, a partir de su
parentNode.
nodoPadre.removeChild(nodoHijo)
.hasChildNodes()
Devuelve true/false si un nodo tiene o no, nodos
descendientes.
32. Javascript
.getAttribute(attrib) Document Object Model
Devuelve el atributo de un nodo.
alert(document.getElementById(“p1”).getAttribute(“id”));
// Muestra p1
.setAttribute()
Cambia el valor de atributo
document.getElementById(“p1”).setAttribute(“class”,”r2”);
.removeAttribute()
Elimina un atributo de un nodo
33. Javascript
Eventos
● Manejadores de Eventos
– EVENTO: método que se activa asíncronamente tras la
sucesión de un proceso determinado.
– Son la esencia principal del Javascript; sin eventos, no hay
interactuación.
– Los eventos lanzan manejadores de eventos, que a su
vez, están vinculados a funciones (o callbacks).
– Javascript no tiene hilos (lo más parecido es utilizar timers
-setTimeout / setInterval).
– La ejecución es completamente lineal, y simplemente se
queda “esperando” a que se lanzar los manejadores de
eventos.
35. Javascript
Eventos
● Fases de Evento
– Fase de Captura de Eventos
● Cuando un usuario lanza un evento, en realidad está
lanzando el evento sobre todos los elementos del árbol
DOM que contienen este elemento.
● CAPTURING
<body>
<div>
<p>
<a href=”http://yahoo.com”>yahoo</a>
</p>
</div>
</body>
36. Javascript
Eventos
– Fase de Retroceso del evento
● Cuando se llega al final de la rama, el evento vuelve hacía
atrás, hasta la raíz del documento.
● BUBBLING
<body>
<div>
<p>
<a href=”http://yahoo.com”>yahoo</a>
</p>
</div>
</body>
37. Javascript
Eventos
● Objeto Evento
– Objeto disponible en los métodos de captura de eventos.
– Es un objeto con propiedades muy útiles a la hora de
interactuar con el evento.
– Dependiendo del tipo de evento, el objeto evento tendrá
unas propiedades u otras.
– El acceso al objeto evento, así como sus propiedades son
dependientes del navegador.
function manejandoEvento(e) {
//en navegadores el objeto evento será recibido como
parámetro.
// en IE, hay que consultar al objeto global window, por la
propiedad event
var e = e? e:window.event; //WORKAROUND!
}
38. Javascript
– Propiedades del evento Eventos
e.target (W3C) / e.srcElement (IE)
● La propiedad más importante que nos posee un evento es
el objeto origen que lo ha invocado.
● Mucho cuidado (Bubbling!!)
e.keyCode
● Devuelve el código ASCII de la tecla pulsada.
e.pageX / e.pageY (No IE)
● Devuelve las coordinadas x e y del puntero del ratón
relativas al documento.
e.screenX / e.screenY
● Devuelve las coordinadas x e y del puntero del ratón
relativas a la pantalla.
e.button
● Identifica qué botón del ratón se ha pulsado:
– IE: 1(izda) / 2(dcha) / 4(centro)
– W3C: 0(izda) / 1(centro) / 2(dcha)
39. Javascript
– Métodos del evento Eventos
e.stopPropagation();
“Frena” la propagación hacía arriba en el DOM del
evento.
En IE: window.event.cancelBubble = true;
e.preventDefault()
“Evita” la acción por defecto del navegador. Esta acción se
ejecuta al finalizar la fase de Event Bubbling.
En IE: window.event.returnValue = true;
40. Javascript
Eventos
● Registrando Eventos
– Llamadas de retroceso Asíncronas
(CALLBACKS ASÍNCRONOS)
● Se registran funciones a las propiedades de los nodos con
el nombre on[evento]:
obj.onclick = function(e) {
var e = e? e:window.event; // Soporte para IE
this == obj;
};
● Siempre vincula los eventos en la fase de retroceso.
● Lo métodos se sobreescriben
41. Javascript
Eventos
– Método propuesto por el W3C
● AddEventListener
elemento.addEventListener('click',funcion,true);
El tercer argumento determina en que fase del evento
lanzar el handler (Capturing/Bubbling).
No se sobreescriben, aun vinculando varios métodos a un
mismo evento.
this == elemento “bindeado”
– Método propuesto por Microsoft
● AttachEvent
elemento.attachEvent ('onclick',funcion);
Microsoft sólo da soporte para la fase de retroceso del
evento.
No se sobreescriben, aun vinculando varios métodos a
un mismo evento.
42. Javascript
AJAX
● XMLHttpRequest
– Objeto interno Javascript, encargado de hacer peticiones
al servidor web y procesar la salida de éstas.
– Creado como control ActiveX por MS, esta implementado
nativamente en otros navegadores (e implementa las
mismas funcionalidades).
– AJAX!
43. Javascript
AJAX
● Instanciando XMLHttpRequest
– Nativamente:
var oXML = new XMLHttpRequest();
– ActiveX
var oXML = new ActiveXObject(“Microsoft.XMLHTTP”);
– CrossBrowser
if (window.XMLHttpRequest)
var oXML = new XMLHttpRequest();
else if (window.ActiveXObject)
var oXML = new ActiveXObject(“Microsoft.XMLHTTP”);
44. Javascript
AJAX
● Métodos XMLHttpRequest
– abort() - Detiene la petición en curso.
– getAllResponseHeaders() - Devuelve todas las cabeceras
de la respuesta (etiquetas y valores) como una cadena.
– getResponseHeader(etiqueta)
● Devuelve el valor de la etiqueta en las cabeceras de la
respuesta.
– open(método,URL,asíncrona,nombre,password)
● Abre una conexión con esa URL mediante ese GET o
POST, aplicando los valores opcionales de la derecha.
– send(contenido) - Envía la petición.
– setRequestHeader(etiqueta,valor)
● Establece el valor de las cabeceras de petición.
45. Javascript
● Propiedades XMLHttpRequest AJAX
– onreadystatechange – Función que se invoca al cambiarse
un estado en la conexión.
– readyState - Estado de la conexión:
● 0 : No iniciado
● 1: Cargando
● 2: Cargado pero sin incorporar el contenido a los objetos
correspondientes.
● 3: Incorporando contenido a los objetos correspondientes.
● 4: Carga completada
– responseText - Datos devueltos por el servidor en formato
string.
– responseXML - Datos devueltos por el servidor en forma
de documento XML que puede ser recorrido mediante
las funciones del DOM.
– status / statusText - Código respuesta HTTP.
46. Javascript
● Ejemplo GET
if (window.XMLHttpRequest)
var oXML = new XMLHttpRequest();
else if (window.ActiveXObject)
var oXML = new ActiveXObject("Microsoft.XMLHTTP");
oXML.open("GET","llamando.php?op1=3");
oXML.onreadystatechange = cambiaestado;
oXML.send(null);
function cambiaestado() {
if (oXML.readyState==4)
alert(oXML.responseText);
}
● Ejemplo POST
var str = “op1=valor1&op2=valor2”;
oXML.open("POST","llamando.php");
oXML.onreadystatechange = cambiaestado;
oXML.setRequestHeader("Content-Type","application/x-www-
form-urlencoded");
oXML.setRequestHeader("Content-Length",str.length);
oXML.send(str);