JavaScript en el Navegador¶
Introducción¶
La mayoría de los navegadores incluyen un intérprete de JavaScript.
Ejecutar código¶
Código embebido¶
Por un lado es fácil ejecutar javascript en el navegador. Basta con crear un fecho demo.html:
<!DOCTYPE HTML>
<html>
<body>
<span onclick="alert('Hello World!');">Click Here</span>
</body>
</html>
Mostrará el texto “Click Here”, y al hacer ‘click’ mostrará una alerta con el texto “Hello World”.
Referencias a ficheros¶
Podemos crear un fichero externo, referenciarlo en la página web y llamar a las funciones que en él aparecen.
Fichero con el código JavaScript codigo.js:
function showAlert () {
window.alert('Hello World!')
}
Y lo referenciamos en el HTML:
<!DOCTYPE HTML>
<html>
<body>
<span onclick="showAlert();">Click Here</span>
</body>
</html>
Consola¶
En Firefox podemos abrir una consola asociada a una página web mediante Ctrl+May+K. En dicha consola podemos ver algunas de las variables globales asociadas:
>> window
Window → file:///C:/Users/C08937/Documents/src/javascript/ex01/02.html
Si hacemos click en Window, Firefox nos mostrará todos los métodos y parámetros asociados. De los muchos que hay, podemos probar:
>> window.alert('Pepe')
Pero, sobretodo, destacamos:
>> window.document
Este último es el que contiene la estructura DOM (Document Object Model).
Peculiaridades¶
La cantidad de cosas que el código JavaScript puede hacer en el navegador es muy limmitada para minimizar los riesgos de seguridad. A esto se le llama sandboxing.
No todos los navegadores cumplen en igual medida los estándares. Programar en el navegador es un ambiente hostil.
DOM (Document Object Model)¶
La página web es un documento. Daremos una visión rápida por culturilla, aunque en la práctica tenderemos a usar la librería jQuery.
En la consola del navegador:
>> window.document.documentElement
<html>
A partir de aquí, tenemos una estructura jerárquica que tendrá una pinta parecida a la siguiente:
html
head
-title
body
- h1
- div
- p
- a
- ...
- p
Cada nodo tendrá un nodeType. Dichos tipos vienen definidos en la propia definición del documento:
>> window.document.TEXT_NODE
3
>> window.document.COMMENT_NODE
8
Advertencia
el DOM es una interfaz genérica y no está especialmente bien integrado con JavaScript. Por ejemplo childNodes es una instancia de NodeList que no contiene métodos como slice o forEach.
Existen métodos que permiten obtener referencias a nodos próximos:
- childNodes
- firstChild
- previousSibling
- nextSibling
- lastChild
- parentNode
Encontrar elementos¶
Por ejemplo:
>> window.document.getElementsByTagName('a')
HTMLCollection [....]
>> window.document.getElementsByTagName('a')[0].href
"file:///C:/Users/C08937/AppData/Roaming/Mozilla/Firefox/Profiles/3870q4ru.default/ScrapBook/data/20140808180713/index.html"
De la misma forma tenemos métodos como:
- window.document.getElementById
- getElementsByClassName
Modificar el documento¶
Por ejemplo:
- removeChild
- appendChild
- insertBefore
- replaceChild
- createTextNode
Atributos¶
Normalmente son accesibles como propiedades de la instancia del nodo.
El contenido textual del nodo viene:
- textContent
También se puede usar:
- getAttribute
- setAttribute
Layout¶
Los elementos de una página web ocupan una posición en el navegador. Podemos obtener la información asociada mediante:
- offsetHeight: altura que ocupa el elemento
- offsetWidth: ancho que ocupa el elemento
- clientHeight: altura disponible en el interior del elemento
- clientWidth: anchura disponible en el interior del elemento
- getBoundingClientRect: devuelve el bounding box en la pantalla (top, bottom, left, right).
- pageXOffset / pageYOffset: nos devuelve el offset asociado al scrolling.
Estilos¶
Por ejemplo:
<p><a href=".">Normal link</a></p>
<p><a id="para" href="." style="color: green">Green link</a></p>
Podemos editarlo en JavaScript mediante:
var para = document.getElementById("para");
console.log(para.style.color);
para.style.color = "magenta";
CSS¶
Query Selectors¶
querySelectorAll
Posicionar y animar¶
Events¶
Usaremos addEventListener(<evento>, <callback>):
var button = document.querySelector("button");
button.addEventListener("click", function(event) {
console.log("Button clicked.");
});
También tenemos removeEventListener.
Por otro lado, tenemos onclick para los nodos.
Los callback reciben como parámetro el objeto event:
Propagación¶
Los padres reciben eventos producidos en los hijos.
Un event handler puede llamar al método stopPropagation:
event.stopPropagation()
También se puede inspeccionar target que contiene el nodo en el que se originó el evento:
event.target
Podemos evitar que ocurra el comportamiento predefinido:
event.preventDefault()
Advertencia
no conviene hacer esto salvo que tengamos un buen motivo para hacerlo.
Eventos de teclado¶
Tenemos:
- keydown
- keyup
- keypress
Después inspeccionamos el objeto event para ver si su contenido está asociado a las teclas que nos interesan. Para ello veremos el contenido de keyCode y ctrlKey:
addEventListener("keydown", function(event) {
if (event.keyCode == 32 && event.ctrlKey)
console.log("Continuing!");
});
Eventos del ratón¶
Por ejemplo:
- mouseup
- mousedown
- click
- dblclick
El evento puede generar:
event.pageX
event.pageY
El movimiento del ratón:
- mousemove
- mouseover
- mouseout
Advertencia
estos eventos también se propagan. Es útil relatedTarget en este caso.
Scroll events¶
Tenemos el evento:
- scroll
Y podemos analizar los valores de:
document.body.scrollHeight
innerHeight
innerWidth
pageXOffset
pageYOffset
...
Load event¶
Este evento se lanza mientra carga la página:
- load
- beforeunload: antes de cerrar una página.
Ejecución de un script¶
Qué lanza la ejecución de un script:
- Encontrar <script>
- Que se dispare un evento
- La función requestAnimationFrame (llama a una función antes del redraw de otra página)
Advertencia
los script nunca se ejecutan en paralelo. Si un script tarda mucho en ejecutarse, la página se congela. Existen los Web Workers, que permiten generar un entorno de ejecución aislado.
Web workers funcionan mediante el envío de mensajes:
var squareWorker = new Worker("code/squareworker.js");
squareWorker.addEventListener("message", function(event) {
console.log("The worker responded:", event.data);
});
squareWorker.postMessage(10);
squareWorker.postMessage(24);
Se puede poner timeout a la ejecución de funciones:
var bombTimer = setTimeout(function() {
console.log("BOOM!");
}, 500); // 500ms
Los timeout también pueden eliminarse:
clearTimeout(bombTimer);
De la misma forma que para requestAnimationFrame existe cancelAnimationFrame.
Para funciones que deben ejecutarse cada cierto periodo de tiempo tenemos setInterval y clearInterval:
var ticks = 0;
var clock = setInterval(function() {
console.log("tick", ticks++);
if (ticks == 10) {
clearInterval(clock);
console.log("stop.");
}
}, 200);
Debouncing¶
Es la técnica por la que evitamos cierto comportamiento con eventos que se disparan muy rápido.