programacion_web
programacion_web
https://creativecommons.org/licenses/by-sa/4.0/deed.es
1
Índice
1. HTML 5
1.1. Introducción a HTML . . . . . . . . . . . . . . . . . . . . . . 5
1.2. Lenguajes de marcado . . . . . . . . . . . . . . . . . . . . . . 5
1.3. Versiones de HTML . . . . . . . . . . . . . . . . . . . . . . . . 7
1.4. Sintaxis de HTML . . . . . . . . . . . . . . . . . . . . . . . . 10
1.5. Cabecera del documento . . . . . . . . . . . . . . . . . . . . . 16
1.6. Cuerpo del documento . . . . . . . . . . . . . . . . . . . . . . 19
1.7. Formularios . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.8. Elementos obsoletos . . . . . . . . . . . . . . . . . . . . . . . . 33
1.9. Entities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3. Bootstrap 5 55
3.1. Características . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.2. Rejilla de Bootstrap . . . . . . . . . . . . . . . . . . . . . . . 59
3.3. Componentes de Bootstrap . . . . . . . . . . . . . . . . . . . . 63
3.4. Formularios . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
4. JavaScript(i) 69
4.1. Introducción a JavaScript . . . . . . . . . . . . . . . . . . . . 69
4.2. Holamundo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
4.3. node.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
4.4. Sintaxis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
4.5. Tipos de datos . . . . . . . . . . . . . . . . . . . . . . . . . . 80
4.6. Identicadores . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
4.7. Operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
4.8. Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
4.9. Tipos de variables . . . . . . . . . . . . . . . . . . . . . . . . . 95
4.10. Sentencias de control . . . . . . . . . . . . . . . . . . . . . . . 98
4.11. Procesamiento de cadenas . . . . . . . . . . . . . . . . . . . . 101
4.12. Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
4.13. Plain Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
2
4.14. Excepciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
4.15. Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
6. JavaScript(ii) 145
6.1. Números aleatorios . . . . . . . . . . . . . . . . . . . . . . . . 145
6.2. Fecha y Hora en JavaScript . . . . . . . . . . . . . . . . . . . 145
6.3. Módulos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
6.4. TypeScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
6.5. POO basada en prototipos . . . . . . . . . . . . . . . . . . . . 154
6.6. POO basada en herencia . . . . . . . . . . . . . . . . . . . . . 157
8. Json 168
8.1. Introducción a JSON . . . . . . . . . . . . . . . . . . . . . . . 168
8.2. Funciones para procesar JSON . . . . . . . . . . . . . . . . . . 172
9. AJAX 173
9.1. Introducción a Ajax . . . . . . . . . . . . . . . . . . . . . . . . 173
9.2. JSONP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
9.3. Ejemplo: cambio de divisas . . . . . . . . . . . . . . . . . . . . 176
3
11.Express 182
11.1. Introducción a Express . . . . . . . . . . . . . . . . . . . . . . 182
11.2. Instalación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
11.3. Diseño de las URL . . . . . . . . . . . . . . . . . . . . . . . . 183
11.4. API REST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
11.5. Conguración de Express . . . . . . . . . . . . . . . . . . . . . 184
11.6. Status Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
11.7. Ejemplo completo . . . . . . . . . . . . . . . . . . . . . . . . . 189
11.8. Ficheros estáticos . . . . . . . . . . . . . . . . . . . . . . . . . 190
4
1. HTML
En esta misma época, año 2005, la aparición de AJAX permite que las
aplicaciones web comiencen a semejarse a las aplicaciones de escritorio
5
Ejemplo de lenguaje de marcado muy elemental: redacto un docu-
mento en un procesador de textos, lo imprimo y alguien lo revisa,
incluyendo anotaciones a mano. Las anotaciones (metainforma-
ción) se distingue fácilmente del texto original
XML
XML Extensible Markup Language
Es una forma de describir datos jerárquicamente. Estándar para trans-
ferir información entre distintos sistemas sin tener que adaptarlos a
cada plataforma concreta, y de forma que sea fácil de leer por un hu-
mano y fácil de procesar por un ordenador
6
En HTML, como en cualquier lenguaje de marcado, es esencial separar
los aspectos semánticos del texto del formato de la representación gráca
Para los usuarios, WWW e internet son sinónimos. Pero nosotros de-
bemos distinguirlo
7
El resto de servicios de internet siguen diferenciándose del WWW,
pero casi todos ellos acaban teniendo un interfaz de usuario web,
lo que hace que el usuario lo perciba como la misma cosa
8
El desarrollo de HTML lo retoma el WHATWG (Web Hypertext Ap-
plication Technology Working Group: Google Apple, Mozilla, Opera)
Audio y video
Grácos vectoriales
Adobe Flash
Otra de las grandes ventajas de HTML 5 es que permite prescindir de
Flash
Adobe Flash era una plataforma software desarrollada por Adobe Sys-
tems para mostrar animaciones, grácos vectoriales, vídeos, audio, con-
tenido interactivo...
9
Muy problemático. Ya en el año 2000 se publican artículos como Flash:
99 % Bad, (J.Nielsen)
No estándar. Dependencia del fabricante. Anima a desarrollar conteni-
do centrado en la apariencia gráca externa, no en la usabilidad y la
semántica
Signo de menor
Nombre de la etiqueta
Signo de mayor
Ejemplo:
<h1>
Una etiqueta de cierre está formada por:
10
Signo de menor
Barra ( slash )
Nombre de la etiqueta
Signo de mayor
Ejemplo:
</h1>
Ejemplo :
< h1>
Esto es un ERROR
Ejemplo :
<h1 >
Ejemplo:
<br></br>
Esto es un ERROR
11
Elementos de tipo void muy habituales son: br, hr, meta, link, img, input
En HTML 4.01 también son de tipo void: area, base, col, param
HTML 5 añade: source
Párrafos:
<p>
Viñetas:
Tablas:
Algunos más
12
Sintaxis de HTML: distribución de los elementos
Un documento HTML está formado por
Declaración de tipo
◦ Codicación de caracteres
Un elemento body
<!DOCTYPE html>
<html>
<head>
<title>Hola mundo en HTML</title>
<meta charset="utf-8">
</head>
<body>
Hola, mundo.
</body>
</html>
13
Validación del código
En esta asignatura haremos énfasis en generar siempre código correcto,
tomando como referencia el W3C Markup Validation Service
Tu código no puede dar ningún error
Cuidado:
DOCTYPE
La declaración <!DOCTYPE html> es obligatoria al comienzo de un docu-
mento HTML 5
Case insensitive
HTML es insensible a mayúsculas ( case insensitive ), aunque lo habitual
es usar siempre las minúsculas.
Hay una excepción:
<!DOCTYPE html>
<!doctype html>
Ambas formas son idénticas y correctas, pero lo habitual es usar la pri-
mera, posiblemente por inuencia de XHTML (que es sensible a mayúsculas,
y donde la única forma válida es la primera)
14
Comentarios
Los comentarios son iguales que en XML. Se pueden poner en cualquier
lugar del documento
<!-- Esto es un comentario -->
Etiquetas autocerradas
En XML, cuando un elemento no tiene texto, hay dos alternativas posibles
<holamundo></holamundo>
Usar una etiqueta autocerrada
<holamundo/>
Signo de menor, nombre, barra, signo de mayor
Atributos
Dentro de la etiqueta de apertura puede haber uno o más atributos, que
son modicadores del elemento
Ejemplo:
<html lang="es-ES">
<!-- etc etc -->
Esto es texto en español de España
<!-- etc etc -->
</html>
15
Un atributo es un par formado por un nombre y un valor. Su sintaxis
es
Signo igual
16
CSS
CSS ( Cascading Style Sheets ) es un lenguaje de diseño gráco para crear
hojas de estilo, que son son una sucesión de reglas que especican el formato
gráco de un documento
Las hojas CSS pueden ubicarse
Es de tipo void
Puede aparecer varias veces, pero solo en la sección head nunca
en body
No confundir con los enlaces a otros documentos HTML dentro
del cuerpo del documento, que se indican con <a>
Elemento meta
Contiene diversos atributos con metainformación
<head>
<meta charset="UTF-8">
<meta name="description" content="Tutorial sobre tecnologías web">
<meta name="keywords" content="HTML,CSS,Bootstrap,JavaScript">
<meta name="author" content="Juan García">
</head>
17
Codicación de caracteres
En HTML antiguo lo habitual era emplear la codicación ISO-8859. En
europa occidental, ISO-8859-1, también llamada latin1. O más bien windows-
1252, que es muy similar
<head>
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
...
</head>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
...
</head>
En HTML 5 :
<meta charset="UTF-8">
Problema: Hay varios lugares donde indicar la codicación
18
1.6. Cuerpo del documento
Cuerpo del documento
El elemento body contiene el cuerpo del documento, su contenido princi-
pal
Block elements
Siempre empiezan por nueva línea, y se muestran con cierto margen
antes y después del elemento
p
Párrafo: secuencia de oraciones con unidad temática. Acaba en punto y
aparte
Un salto de línea
19
Dentro de un <p> hay elementos
Atención:
cabría espera que elW3C Validator nos dijera algo como elemento no
permitido dentro de párrafo
Pero lo que sucede es que como un h1 no puede estar incluido dentro
de un <p>, se supone que hay un cierre implícito del párrafo antes de
empezar el h1
<p>Hola, mundo.</p><h1>Encabezado 1</h1></p> <!-- ERROR -->
br
La etiqueta <br> dene el elemento breaking line
En un documento HTML, los saltos de línea se ignoran
20
em
La etiqueta <em> dene el elemento emphasized
pre
La etiqueta <pre> dene el elemento texto preformateado
El navegador muestra el texto respetando los espacios entre palabras y
los saltos de línea
<pre>
#include <stdio.h>
int main() {
printf("Hello World!");
return 0;
}
</pre>
h1-h6
Las etiquetas <h1>, <h2>, ... <h6>, denen elementos heading (encabeza-
do)
a
La etiqueta <a> dene el elemento anchor (ancla), que sirve para hacer
anclas y también para hacer hiperenlaces
Su nombre es poco afortunado, no describe lo que hace
21
La invención del hipertexto se atribuye a D.Engelbart y T.Nelson, por
separado, en 1962/1963
<a href="mailto:[email protected]?Subject=Contacto%20web">
Envíame un correo</a>
(Aunque hoy esto no es recomendable porque la dirección de correo
queda expuesta a los spammers)
O enlazar un script
<a href="http://linkedsite/url.html">Documento</a>
Absolutos dentro del mismo sitio
22
anchors
Un anchor es una referencia a un punto concreto dentro de un documento
https://gsyc.urjc.es/~mortuno/index_at.html#evaluacion
<a href="https://www.urjc.es/universidad/org#rector>rector</a>
<a href="#inicio>inicio</a>
Ejemplo
[.....]
23
Anchor al estilo HTML 5
En HTML 5, un anchor se crea añadiendo el atributo id a cualquier
elemento contenedor p, h1, div, pre...
[.....]
Atributo target
Añadiendo a un enlance el atributo target="_blank", este se abrirá en
una nueva pestaña del navegador
div
La etiqueta <div> dene una división o sección dentro del documento
Ejemplo
<div class="respuesta">Todas son falsas</div>
En HTML 5, además de este elemento se denen otros con el mismo
propósito, pero con una semántica más especíca
24
span
La etiqueta <span> (espacio, longitud, lapso) dene una división o sección
dentro del documento
Muy similar a div, pero no crea un bloque nuevo y por tanto, no crea
una nueva línea
<table>
<tr>
<th>Cabecera, primera columna</th>
<th>Cabecera, segunda columna</th>
</tr>
<tr>
<td>Primera fila, primera columna</td>
<td>Primera fila, segunda columna</td>
</tr>
<tr>
<td>Segunda fila, primera columna</td>
<td>Segunda fila, segunda columna</td>
</tr>
</table>
ol,li
Las etiquetas <ol> (ordered list), <li> (list item), permiten crear listas
numeradas
<ol>
<li>Sota</li>
<li>Caballo</li>
<li>Rey</li>
</ol>
25
Las listas numeradas usan, por omisión, números naturales para cada
item
ul,li
Las etiquetas <ul> (unordered list), <li> (list item), permiten crear listas
sin numerar
<ul>
<li>Sota</li>
<li>Caballo</li>
<li>Rey</li>
</ul>
dl,dt,dd
Las etiquetas <dl> (description list), <dt> (description term), <dd> (des-
cription), permiten crear listas de descripciones o deniciones de términos
<dl>
<dt>
Nombre
</dt>
<dd>
Juan García
</dd>
<dt>
Centro de origen
</dt>
<dd>
ESTIT-URJC
</dd>
</dl>
26
img
La etiqueta <img> permite insertar imágenes
Ejemplos
<a href="https://www.urjc.es">
<img src="images/urjc.png" width="120" alt="logo de la URJC">
</a>
urjc.png
El directorio padre del directorio donde está este html, hay un directorio
llamado practica03, y dentro, un chero llamado urjc.png
27
Si anteponemos la barra, el signicado cambia por completo
/urjc.png
Observa que un path que incluya la dirección absoluta del usuario casi
siempre es un error muy severo, porque deja de funcionar en cuanto
cambia el usuario o la máquina
/home/alumnos/jperez/images/urjc.png
1.7. Formularios
form
Un formulario HTML es un elemento que permite aceptar entrada de
información por parte del usuario.
<form>
(Elementos del formulario)
</form>
28
Los elementos posibles son varios
<form action="/action_page.html">
Nombre de usuario:<br>
<input type="text" name="usuario" ><br>
Contraseña:<br>
<input type="password" name="contrasenya" ><br><br>
País:<br>
<input type="text" name="pais" value="España" ><br><br>
<input type="submit">
</form>
Observa que
29
input: radio
<input type="radio"> dene un radio button, que permite elegir una (y
solo una) opción entre varias
<form>
<input type="radio" name="os" value="Linux" checked>Linux<br>
<input type="radio" name="os" value="macOS" >macOS<br>
<input type="radio" name="os" value="Windows">Windows<br>
<input type="radio" name="os" value="other">Otro<br>
</form>
input: checkbox
Checkbox es un tipo de input que permite elegir 0 o más opciones de una
lista
<form>
<input type="checkbox" name="terminos" value="si">
He leido los términos y condiciones<br>
<input type="checkbox" name="publicidad" value="si">
Deseo recibir comunicaciones comerciales<br>
</form>
month
number
range
search
tel
time
30
url
week
eldset
Un conjunto de entradas se pueden agrupar en un <fieldset>, con un
título indicado en un elemento <legend>
<form>
<fieldset>
<legend>
Datos personales
</legend>
Elija un color:
<input type="color" name="favcolor">
<br> Fecha de nacimiento:
<input type="date" name="nacimiento">
<br> Fecha y hora de nacimiento:
<input type="datetime-local" name="nacimiento-hora">
<br> E-mail:
<input type="email" name="email">
<br> Indica un número del 1 al 10:
<input type="number" name="numero" min="1" max="10">
<br>
<input type="submit">
</fieldset>
</form>
select
El elemento <select> permite elegir una opción entre varias
<form>
Indique el departamento:
<select name="departament">
<option value="sales">Comercial</option>
<option value="technical">Técnico</option>
<option value="webmaster">Webmaster</option>
</select>
<input type="submit">
</form>
31
El elemento <datalist> es similar pero permite que el usuario escriba
una respuesta distinta a las propuestas
textarea
Con el elemento <textarea> el usuario puede introducir varias líneas de
texto
<form>
<textarea name="mensaje" rows="10" cols="30">
Escriba aquí su mensaje.
</textarea>
</form>
label
Para que el usuario sepa qué es cada elemento de un formulario, se puede
usar:
Un elemento <label>
Ventajas:
<form>
<label for="ciudad">Ciudad de procedencia:</label>
<input type="text" name="ciudad" id="ciudad">
<input type="submit">
</form>
id lo usa el navegador
32
Típicamente se hace que coincidan pero son independientes, no tienen por
qué ser iguales
En el caso del <input type="radio"> y el <input type="checkbox">
color
font
u (underline)
1
Todos ellos han desaparecido en HTML 5, en su lugar debe usarse CSS
1.9. Entities
Entities
Las entities se usan para
1 En el elemento span sigue siendo legal usar atributos grácos, pero no es recomendable.
Siempre es preferible CSS
33
Cada entity tiene un nombre y un número, se puede usar cualquier de las
dos formas
<
< <
>
> >
€ €
Ñ Ñ
ñ ñ
Siempre se representa
Nunca se usa para partir una linea. Ejemplo: para escribir 2 ¿ con
garantías de que ambos símbolos estarán en la mísma línea:
2 €
34
Material complementario
HyperText Markup Language (Wikibook):
http://en.wikibooks.org/wiki/HTML_Programming
HTML5: A tutorial for beginners:
http://www.html-5-tutorial.com/
Dive into HTML5:
http://diveintohtml5.info
HTML5 (Wikipedia):
http://en.wikipedia.org/wiki/HTML5
Web Fundametals (Code Academy):
http://www.codecademy.com/tracks/web
35
2. Hojas de estilo CSS
36
</head>
<body>
<h1><font color="red" face="Arial" size="5">
Titular de la página
</font></h1>
<p><font color="gray" face="Verdana" size="2">
Un párrafo de texto no muy largo.
</font></p>
</body>
</html>
Con CSS
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ejemplo de estilos con CSS</title>
<style>
h1 { color: red; font-family: Arial; font-size: large; }
p { color: gray; font-family: Verdana; font-size: medium; }
</style>
</head>
<body>
<h1>Titular de la página</h1>
<p>Un párrafo de texto no muy largo.</p>
</body>
</html>
<style>
body { background-color: lightgray; }
</style>
37
Elemento link en la cabecera, apuntando a a chero .css. Normalmente
es la opción preferible
https://www.w3schools.com/css/css_howto.asp
<script src="script.js"></script>
Regla: cada uno de los estilos que componen una hoja de estilos CSS.
Cada regla está compuesta de una parte de selectores, un símbolo
de llave de apertura ({), otra parte denominada declaración y por
último, un símbolo de llave de cierre (}).
38
Glosario Básico (y II)
2.3. Selectores
Selectores
A un mismo elemento HTML se le pueden aplicar varias reglas
CSS 2.1 incluye una docena de tipos diferentes de selectores, que permi-
ten seleccionar de forma muy precisa elementos individuales o conjuntos
de elementos dentro de una página web.
Resumen:
39
Significado
----------------------------------
(espacio) descendiente (hijo, nieto...)
. clase
, OR
(concatenación) AND
# id
Selectores básicos
1. Selector universal
3. Selector descendiente
4. Selector de clase
5. Selector de identidad
Selector Universal
No se utiliza habitualmente
* {
margin: 0;
padding: 0;
}
Se pueden agrupar todas las reglas individuales en una sola regla con
un selector múltiple. La coma signica or
Buena práctica: agrupar los atributos comunes de varios elementos en
una única regla CSS y posteriormente denir los atributos especícos
de esos mismos elementos
40
h1, h2, h3 {
color: #8A8E27;
font-weight: normal;
font-family: Arial, Helvetica, sans-serif;
}
h1 { font-size: 2em; }
h2 { font-size: 1.5em; }
h3 { font-size: 1.2em; }
Selector descendiente
Selecciona los elementos contenidos dentro de otros elementos.
Ejercicio
¾Qué elementos se seleccionarían con estos tipos de selectores?
p a { color: red; }
p * a { color: red; }
41
Selector de clase
Se utiliza el atributo class de HTML sobre ese elemento para indicar
directamente la regla CSS que se le debe aplicar
Se crea en el archivo CSS una nueva regla llamada destacado con todos
los estilos que se van a aplicar al elemento
<style>
.comentario {color : blue;}
.noticia {color : red;}
.obsoleto {text-decoration : line-through;}
</style>
[...]
<body>
<p class="comentario"> Lorem ipsum dolor sit amet<p>
<p class="comentario obsoleto"> consectetur adipisicing elit, </p>
<p class="noticia "> sed do eiusmod tempor incididunt </p>
<p class="noticia obsoleto"> ut labore et dolore magna aliqua.</p>
</body>
Ejemplo:
http://ortuno.es/ej000_clases.html
42
Selector de clase más especíco
Combinando el selector de tipo y el selector de clase, se obtiene un
selector mucho más especíco.
Esta regla se aplica a los elementos de tipo párrafo, que además sean de
clase destacado. (En este ejemplo, solo una vez)
.a.b {...}
Esta regla se aplica a los elementos de clase a que además sean de clase b
http://ortuno.es/concatenacion_clases.html
Ejercicio
¾Qué elementos se seleccionarían con estos tipos de selectores?
p.aviso { ... }
p .aviso { ... }
p, .aviso { ... }
*.aviso { ... }
43
Selectores de identicador
Aplica estilos CSS a un único elemento de la página
<p>Primer párrafo</p>
<p id="destacado">Segundo párrafo</p>
<p>Tercer párrafo</p>
Ejercicio
¾Qué elementos se seleccionarían con estos tipos de selectores?
p#aviso { ... }
p #aviso { ... }
p, #aviso { ... }
*#aviso { ... }
44
2.4. Unidades y colores
Unidades de medida
Unidades absolutas
Unidades relativas
em, ex, px
Porcentajes
Pixel y porcentajes
Para denir el layout (la distribución) del documento. Esto es, la an-
chura de las columnas y de los elementos de las páginas
em y porcentajes
Mediante su nombre
red, cyan, blue, darkblue, lightblue, purple, yellow, lime, magenta, whi-
te, silver, gray/grey, black, orange, brown, maroon, green, olive
https://www.w3schools.com/colors/colors_names.asp
Ejemplos:
45
Código Nombre Pantone
-----------------------
#ff0000 red
#ff2800 ferrari red
#f5e050 minion yellow
color
backgroud-color
border-color
Cada vez que pulsemos espacio nos mostrará una nueva paleta de barras
verticales, con un componente aleatorio pero siguiendo ciertas normas
de diseño gráco
46
Por omisión las paletas son de cinco colores
Cuando nos guste un color, lo podemos jar con el icono del candado:
cuando sigamos pulsando espacio, esa barra se mantendrá
El icono view shades de cada barra, con forma de rejilla, nos permite
modicar ese color
Subrayado
Tamaño
Estilo
47
Atributos relacionados con los bordes
Los atributos del borde de una caja se especican con:
border-width
border-style
border-color
https://www.w3schools.com/css/css_border.asp
48
49
2.6. El Modelo de Cajas
El modelo de cajas
Es el comportamiento de CSS que hace que todos los elementos de las
páginas se representen mediante cajas rectangulares
Cada vez que se inserta una etiqueta HTML, se crea una nueva caja
rectangular que encierra los contenidos de ese elemento
su borde
50
51
Imagen de fondo (background image): imagen que se muestra por
detrás del contenido y el espacio de relleno.
div {
width: 300px;
padding-left: 50px;
padding-right: 50px;
margin-left: 30px;
margin-right: 30px;
border: 10px solid black;
}
Ejemplos:
http://ortuno.es/cajas.html
margin: 8px
52
Margen, relleno, bordes y modelo de cajas (y II)
Visualización
CSS dene otros cuatro atributos para controlar su visualización: dis-
play, visibility, overow y z-index.
Otros atributos
CSS tiene muchos otros atributos que no veremos aquí
53
54
3. Bootstrap 5
3.1. Características
¾Qué es Bootstrap?
Bootstrap es un framework libre para desarrollo web
Características de Bootstrap
Ventajas
Es software libre
Inconvenientes
Al ser una herramienta muy popular, las páginas web que no estén
personalizadas quedan iguales que las de todo el mundo
No es especialmente fácil personalizar los estilos (Foundation puede ser
más adecuado para esto)
55
Holamundo en Bootstrap
Para usar Bootstrap basta con
Denir el viewport
Incluir un elemento link apuntando al CSS de Bootstrap
<!doctype html>
<html lang="es-ES">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
rel="stylesheet" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
crossorigin="anonymous">
</script>
<body>
<div class="container">
<h1>Holamundo en Bootstrap 5</h1>
</div>
</body>
</html>
http://ortuno.es/hola_bootstrap5.html
1. Técnica inicial
56
Viewport
Para diseñar webs en dispositivos móviles, es importante tener claro qué
es el viewport y cómo se comporta
Viewport virtual
Con la aparición de los navegadores en teléfonos móviles, los cambios del
tamaño de la pantalla son mucho más drásticos. La técnicas tradicionales
siguen funcionando, pero proporcionan una experiencia de uso muy poco
satisfactoria
57
El usuario arrastra el viewport físico (la pantalla real, más pequeña)
sobre el viewport virtual, para que le muestre una zona u otra del
documento. También se le puede permitir hacer zoom
Páginas responsive
Una página web moderna con un minimo de calidad se entiende que tiene
que ser responsive
La página se adapta al tamaño de la pantalla (escritorio, tablet, móvil),
sin usar la barra de desplazamiento horizontal, que es muy incómoda.
La barra de desplazamiento vertical se sigue usando, no es molesta
XXXXXXXXXXXX
En un tablet
XXXXXX
XXXXXX
En un móvil
XXXX
XXXX
XXXX
58
Mobile rst
Con una propiedad de etiqueta meta, podemos indicar la escala inicial
del viewport
Como las páginas con bootstrap son responsive, especicamos que el
viewport virtual coincida con el ancho de la pantalla, esto es, con el
viewport ordinario. En otras palabras: que no haya un viewport virtual
http://ortuno.es/container.html
http://ortuno.es/container_fluid.html
59
El sistema de cuadrículas de Boostrap
La pantalla se divide en las y columnas
En cada la hay hasta 12 casillas, que el diseñador decide cómo repartir
entre celdas
Cada la es un elemento div de HTML con la clase row. Observa que
empleando notación de los selectores de CSS (donde el punto signica
clase ), podemos llamarle .row
Dentro de la la hay elementos a los que en esta asignatura llamamos
celdas, que pueden ser de los tipos .col-N, .col-sm-N, .col-md-N,
.col-lg-N, .col-xl-N o .col-xxl-N
Ejemplo:
<div class="row">
<div class="col-md-4">
</div>
</div>
.col-N
3 en realidad Bootstrap no usa este concepto, habla solo de columna, pero entendemos
que es una terminología confusa: un ladrillo individual no puede ser una columna, hacen
falta varios ladrillos apilados
60
.col-sm-N
.col-md-N
.col-lg-N
.col-xl-N
.col-xxl-N
Columnas .col-xxl-N
Disposición normal en pantallas extra grandes.
Se apilan en pantallas muy grandes, grandes, medianas, pequeñas o
muy pequeñas
Columnas .col-xl-N
Disposición normal en pantallas muy grandes o extra grandes.
Se apilan en pantallas grandes, medianas, pequeñas o muy pequeñas
Columnas .col-lg-N
Disposición normal en pantallas grandes, muy grandes o extra grandes.
Se apilan en medianas, pequeñas o muy pequeñas
Columnas .col-md-N
Disposición normal en pantallas medianas, grandes, muy grandes o extra
grandes.
Se apilan en: pequeñas o muy pequeñas
61
Columnas .col-sm-N
Disposición normal en pantallas pequeñas, medianas, grandes, muy gran-
des o extra grandes.
Se apilan en muy pequeñas
Columnas .col-N
Disposición normal en cualquier pantalla: muy pequeñas, pequeñas, me-
dianas, grandes, muy grandes o extra grandes.
Nunca se apilan
Esto parece un poco complicado, pero con el siguiente ejemplo verás que
no:
1. Vete a
http://ortuno.es/rejilla_01.html
2. Maximiza la ventana
62
El resultado de usar las distintas clases de alineamiento horizontal. En
este caso con dos columnas de 3 casillas cada una
btn
table
card
carousel
y otras utilidades responsivas
Colores contextuales
La gama concreta de colores se decidirá en el CSS. Aquí pondremos clases
con valor semántico.
Con alguna excepción como light o white, puesto que al elegir el color
del fondo, puede ser necesario indicar también el color del texto (en
este ejemplo, el texto blanco sobre fondo blanco no se ve)
<h2>Colores del texto</h2>
<p class="text-muted">Muted (silenciado, apagado).</p>
<p class="text-primary">Primary.</p>
<p class="text-success">Success (éxito).</p>
<p class="text-info">Info.</p>
<p class="text-warning">Warning.</p>
<p class="text-danger">Danger.</p>
<p class="text-secondary">Secondary.</p>
<p class="text-body">Body (típicamente negro).</p>
<p class="text-light">Light grey .</p>
<p class="text-white">White.</p>
<h2>Colores del fondo</h2>
<p class="bg-primary text-white">Primary.</p>
<p class="bg-success text-white">Sucess (éxito)</p>
<p class="bg-info text-white">Info.</p>
<p class="bg-warning text-white">Warning.</p>
<p class="bg-danger text-white">Danger.</p>
<p class="bg-secondary text-white">Secondary.</p>
<p class="bg-dark text-white">Dark (grey).</p>
<p class="bg-light text-dark">Light (grey).</p>
http://ortuno.es/colores.html
63
Botones
La clase btn de Bootstrap puede añadirse a los elementos HTML <button>,
<input> y <a>
http://ortuno.es/botones.html
Imágenes
Para modicar el aspecto de una imagen, Bootstrap, nos permite añadir
clases al elemento <img>
Contorno:
rounded
Esquinas redondeadas
rounded-circle
Circular
img-thumbnail
Alineación:
64
oat-start
Izquierda
oat-end
Derecha
mx-auto d-block
centrada
uid
<div class="row">
rounded
<div class="col-xl-12">
<img src="images/plaza_espana.jpg" alt="Plaza de España, Madrid"
width="400" class="rounded">
</div>
</div>
http://ortuno.es/imagenes.html
Tablas
Para dar formato a un elemento <table>, Bootstrap 5 nos ofrece las clases
.table, .table-bordered, .table-hover, .table-dark y .table-striped
<table class="table table-striped">
<thead>
<tr>
<th>Baraja española</th>
<th>Baraja francesa</th>
</tr>
</thead>
<tbody>
<tr>
<td>Caballo</td>
<td>Reina</td>
</tr>
<tr>
<td>Rey</td>
<td>Rey</td>
</tr>
</tbody>
</table>
http://ortuno.es/tablas.html
65
cards
Una tarjeta (card ) es una caja redondeada dividida en cabecera, cuerpo
y pie.
http://ortuno.es/card.html
3.4. Formularios
Formularios
Bootstrap incluye clases para mejorar el aspecto y usabilidad de los for-
mularios
66
A los <checkbox> los metemos en un <div> al que añadimos class="form-check"
A los <input type="radio"> <input type="checkbox"> les añadi-
mos class="form-check-input"
http://ortuno.es/form_b5.html
carousel
El componente carousel muestra fotografías que se desplazas horizontal-
mente, como un pase de diapositivas. Se les puede añadir título o cualquier
otro texto
Los botones
http://ortuno.es/carrusel.html
Deshabilitar elementos
Como hemos visto, muchos elementos bootstrap admiten la clase disabled
para indicar que tengan un aspecto gráco distinto, deshabilitado
67
Depuración
Si la página no tiene el aspecto que buscas:
Comprueba que la estructura de los div está bien, que no has cerrado
ninguno demasiado pronto o demasiado tarde. Un buen editor te ayu-
dará con esto mostrando el código por niveles. P.e atom cuenta con los
atajos Ctrl k Ctrl 1, Ctrl k Ctrl 2, Ctrl k Ctrl 3, etc
Enlaces relacionados
Documentación ocial
https://getbootstrap.com/docs/5.1/getting-started
Tutorial en w3schools
https://www.w3schools.com/bootstrap5/index.php
68
4. JavaScript(i)
node.js
69
JavaScript Everywhere (2)
Mozilla Rhino. Implementación de JavaScript en java. Permite ejecutar
código JavaScript fuera del navegador, en cualquier entorno donde esté
disponible java
Express.js
ECMAScript 3. 1999
ECMAScript 4.
70
Críticas a JavaScript
Es frecuente hacer críticas negativas a JavaScript, por diferentes motivos,
algunos justicados, otros no tanto
> 0.3===0.3
true
> 0.1+0.2===0.3
false
> 0.3-(0.1+0.2)
-5.551115123125783e-17
71
La barrera de entrada para empezar a programar en JavaScript es baja.
Como cualquiera puede programar en JavaScript, el resultado es que en
JavaScript acaba programando cualquiera. Esto es, hay mucho código
de mala calidad
Características de JavaScript
Muy integrado con internet y el web
72
Es dinámico. Los objetos se crean sobre la marcha, sin denir una clase.
A los objetos se les puede añadir propiedades en tiempo de ejecución
Imperativa
Funcional
4.2. Holamundo
Holamundo
JavaScript no tiene una forma nativa de mostrar texto, emplea distintos
objetos, dependiendo de en qué entorno se ejecute
73
<script>
document.write("Hola, mundo");
</script>
</body>
</html>
http://ortuno.es/holamundo01.html
holamundo.js:
console.log("Hola, mundo");
http://ortuno.es/holamundo02.html
74
Normalmente indicaremos el path (trayecto) del chero javascript de ma-
nera relativa. El trayecto no empieza por el carácter barra (/)
holamundo.js
El directorio padre del directorio donde está este html, hay un directorio
llamado practica03, y dentro, un chero llamado holamundo.js
/holamundo.js
75
Naturalmente, estas mismas ideas sobre los trayectos relativos y abso-
lutos, son aplicables en cualquier lenguaje de programación y a cualquier
chero: una imagen jpg, una librería, etc
Observa que un path que incluya la dirección absoluta del usuario casi
siempre es un error muy severo, porque deja de funcionar en cuanto
cambia el usuario o la máquina
/home/alumnos/jperez/js/holamundo.js
<!DOCTYPE html>
<meta charset="utf-8">
<title>Hola, mundo</title>
<script src="js/holamundo.js"></script>
http://ortuno.es/holamundo03.html
4.3. node.js
node.js
El entorno Node.js permite usar JavaScript como un lenguaje de pro-
gramación en el servidor o en la consola
76
¾nodejs o node?
El intérprete de Node.js en principio se llama node
En Linux
Este nombre ya estaba ocupado por otro programa. Así que las
distribuciones Linux lo renombran a nodejs
Si el otro node no está instalado, normalmente /usr/bin/node es
un enlace a /usr/bin/nodejs
Por tanto, podemos usar indistintamente cualquiera de las dos
formas
En macOS
Entorno Linux
Instalación
Ejecución
nodejs holamundo.js
O bien
node holamundo.js
jperez@alpha:~$ ./holamundo.js
77
#!/usr/bin/nodejs
O bien
#!/usr/bin/env nodejs
Entorno macOS
node holamundo.js
#!/usr/bin/env nodejs
4.4. Sintaxis
Comentarios
Los comentarios se pueden indicar de dos formas
78
Sentencias y expresiones
En JavaScript hay
79
use strict
En ECMAScript 5 aparece el modo estricto
Consiste en una serie de restricciones que producen un código de más
calidad, menos propenso a errores. En general debemos usarlo siempre, para
ello basta poner como primera sentencia del script
'use strict'
function f(){
'use strict'
...
}
primitive values :
boolean, number, string, null, undened
Objetos
80
Booleanos
true
false
Números
Strings (cadenas)
'lorem' "ipsum"
En JavaScript hay dos tipos de datos para indicar que falta información
undened
Una variable no ha sido inicializada
null
Es un objeto que no tiene valor. Más o menos podríamos decir que es
un objeto vacío (aunque el verdadero objeto vacío es {})
81
'use strict'
// Variable no declarada todavía
console.log(nombre) // undefined
// Variable declarada
var nombre;
nombre = 'Juan';
console.log(nombre); // juan
function saludo(n){
console.log('Hola, ',n);
}
// Parámetro especificado
saludo('María'); // Hola, María
// Parámetro no especificado
saludo(); // Hola, undefined
if (x===undefined || x===null){
}
82
Esto equivale a
if (!x) {
}
Aunque es menos claro, porque hay otros valores que también son consi-
derados false (false, 0, NaN y la cadena vacía)
Sería más razonable que el tipo de null fuera undened, pero la primera
implementación de JavaScript hacía esto (por error) y luego ya se tomó como
norma
Conversión de tipos
La función global Number() convierte una cadena en número.
'use strict'
let x,y;
x=Number(" 3 ");
console.log(x,typeof(x)); // 3 'number'
y=String(x);
console.log(y,typeof(y)); // 3 string
console.log(Number("23j")); // NaN
83
'use strict'
let x = Number("xyz");
console.log(x); // NaN
console.log(x === NaN); // false
x = NaN;
console.log(x === NaN); // false
console.log(isNaN(x)); // true
> Math.round(4.9)
5
> Math.round(4.45)
4
> Math.round(4.5)
5
> Math.trunc(4.2)
4
> Math.trunc(4.9)
4
> Math.round(-4.9)
-5
> Math.round(-4.1)
-4
Aunque debes recordar que en JavaScript no existe un tipo para los nú-
meros reales y otro para los enteros: todo son números.
4.6. Identicadores
Identicadores
Símbolos que nombran entidades del lenguaje: nombres de variables, de
funciones, etc
Deben empezar por letra unicode, barra baja o dólar. El segundo ca-
racter y posteriores pueden ser cualquier carácter unicode
Aunque los caracteres internacionales como eñes y tildes son fuentes po-
tenciales de problemas: falta de soporte en el teclado del desarrollador,
conguración del idioma en el sistema operativo, etc
84
¾Sensible a mayúsculas?
JavaScript: Sí
HTML: No
CSS: Sí
Identicadores válidos:
5x
#x
Palabras reservadas
Las siguientes palabras tienen un signicado especial y no son válidas
como identicador:
85
null package private protected
public return short static
super switch synchronized this
throw throws transient true
try typeof var void
volatile while with yield
Números especiales
JavaScript dene algunos valores numéricos especiales:
NaN (Not a number), Infinity, -Infinity
'use strict'
let x,y;
x=1/0;
y= -1/0;
console.log(x); // Infinity
console.log(y); // -Infinity
console.log(typeof(x)); // number
console.log(typeof(y)); // number
console.log(typeof(NaN)); // number
4.7. Operadores
Operadores
Los principales operadores son
Operadores aritméticos
+ - * / % ++ --
Operadores de asignación
= += -=
Operadores de cadenas
+ +=
'use strict'
let x;
x=0;
++x;
console.log(x); // 1
x+=2;
console.log(x); // 3
--x;
86
console.log(x); // 2
x-=2;
console.log(x); // 0
x='hola'+'mundo';
console.log(x); // 'holamundo'
x+="!";
console.log(x); // 'holamundo!'
== !=
Hace conversión automática de tipos.
> '4'==4
true
> 0==false
true
> 1==true
true
> 2==false
false
> 2==true
false
> ''==0
true
> '\t123\n'==123
true
> 'true'==true
false
=== !==
Mayor y menor
87
Operadores lógicos
&& || !
> !(true && false)
true
4.8. Funciones
Funciones
Una función es una secuencia de instrucciones empaquetada como una
unidad. Acepta 0 o más valores y devuelve 1 valor.
Las funciones en JavaScript pueden cumplir tres papeles distintos
new Cliente()
Métodos. Funciones almacenadas como propiedad de un objeto
Declaración de funciones
Hay cuatro formas de declarar una función
function suma(x,y){
return x+y;
}
function(x,y){
return x+y;
}
88
Mediante funciones echa (arrow functions )
Es una sintaxis compacta para denir funciones anónimas
x => x + 1;
Función Flecha
La declaración tradicional de una función incluye nombre
function f(x){
return x + 1;
}
function (x){
return x + 1;
}
(x) => {
return x + 100;
}
a => a + 100;
89
(x, y) => x + y + 1;
() => 1;
Si el cuerpo tiene más de una línea, es necesario añadir tanto las llaves
como la palabra return
(a, b) => {
let margen = 0.1;
return a + b + margen;
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
Para evitar denir un nombre que solo se usará una vez, podemos
emplear una función anónima: pasamos como argumento la denición
de una función
Un parámetro
90
Función con nombre como argumento
'use strict'
const NumeroMaximo = 10;
const LongitudMinima = 8;
function revision_a(x){
return (x > NumeroMaximo);
}
function revision_b(x){
return (x.length < LongitudMinima);
}
f( 17, function(x){
const Maximo =10;
return (x >= Maximo);
} ); // Corrige esto y lo otro con 17
91
f("holahola", function(x) {
return (x.length <8);
}); // No hagas nada con holahola
Hoisting
JavaScript hace hoisting (elevación) con las funciones.
El motor de JavaScript mueve las declaración al principio del bloque,
'use strict'
console.log(f(1)); //2
function f(x){
return x+1;
}
'use strict'
function f(x){
console.log(x) // 3
x = x + 1;
console.log(x) // 4
}
let a=3;
92
console.log(a); // 3
f(a);
console.log(a); // 3
'use strict'
function f(a){
a[0] = a[0] + 1;
console.log(a[0]); // 4
}
let x = 3;
let a = [x];
console.log(a); // [3]
f(a);
console.log(a); // [4]
Valor devuelto
Una función siempre devuelve exactamente 1 valor. En caso de que la
función no incluya la sentencia return, el valor es undefined
'use strict'
function f(){
}
console.log(f()); // undefined
function g(){
console.log('hola');
}
console.log(g()); // undefined
Número de parámetros
Muchos lenguajes de programación obligan a que el número de parámetros
en la declaración de una función sea igual al número de argumentos cuando
se invoca.
JavaScript, no. Si faltan argumentos, se consideran undefined y si sobran
se ignoran
93
'use strict'
function f(x,y){
return x+y;
};
console.log(f(1)); // NaN
console.log(f(2,2)); // 4
console.log(f(1,1,1)); // 2
function f(x,y){
console.log("Argumentos recibidos:",arguments.length);
}
f('a'); // 1
f('a','b'); // 2
f('a','b', 'c'); // 3
'use strict'
function f(x){
if (x===undefined) {
x=0};
return x + 1 ;
};
console.log(f()); //1
'use strict'
function f(x){
x = x || 10; // línea 4
return x ;
};
console.log(f(7)); // 7
console.log(f()); // 10
94
Aunque es una solución habitual, no es elegante
'use strict'
function f(x){
x = x || 10;
return x ;
};
console.log(f(false)); // 10
console.log(f(1)); // 1
'use strict'
function f(x=10){
return x;
}
console.log(f(5)); // 5
console.log(f()); // 10
console.log(f(false)); // false
Los motores actuales (año 2023) suelen tener esto implementado. Si son
un poco antiguos, no
95
Locales, declaradas con var. O declaradas implícitamente (si no usamos
el modo estricto)
Globales
http://2ality.com/2015/02/es6-scoping.html#the-global-object
Variables Globales
Son variables accesibles desde todo el script
En el caso de JavaScript incrustado en HTML, todos los scripts incluidos
en la misma página HTML comparten el objeto Window y por tanto, las
variables globales
'use strict'
let x=0; // Global por declararse fuera de función
function f(){
x=3; // Modifica la variable global
}
function g(){
return(x);
}
f();
console.log(g()); //3
'use strict'
function f(){
var x=0; // Variable local de f
g();
console.log(x); //0. No le afecta el cambio en g
96
}
function g(){
var x=3; // Variable local de g
}
f();
El modo estricto obliga a declarar las variables, pero var permite usar
primero y declarar después. Incluso declarar dos veces
'use strict'
// Variable no declarada (todavía)
console.log(nombre) // undefined
// Variable declarada
var nombre = 'Juan';
console.log(nombre); // Juan
Aquí recomendamos usar siempre let, a menos que tengamos que pro-
gramar en una versión antigua de JavaScript
'use strict'
97
'use strict'
function f() {
var x = 1;
if (true) {
var x = 2; // La misma variable. Destruimos valor previo
console.log(x); // 2
}
console.log(x); // 2
}
function g() {
let x = 1;
if (true) {
let x = 2; // Variable diferente, local del bloque
console.log(x); // 2
}
console.log(x); // 1. Mantiene el valor previo
}
f();
g();
(funtion() {
}());
Constantes
Como en muchos otros lenguajes, podemos declarar constantes usando
const. Equivale a declarar con let, solo que el objeto no podrá ser reasignado
'use strict'
const a = 5;
a = 4 ; // ½MAL! TypeError
98
Atención, declarar un objeto con const hace que no se pueda reasignar,
6
pero no signica que sea inmutable. Podremos cambiar sus propiedades
'use strict'
const b={
x:"lorem",
y:"ipsum"
}
'use strict'
var x="ejemplo";
if (x.length < 4){
console.log("Cadena muy corta");
};
if (2 > 0) {
console.log("cierto");
}
else {
console.log("falso");
};
if (2 > 0) console.log("cierto");
else console.log("falso");
switch
Evalúa la expresión entre paréntesis después de switch y salta a la cláu-
sula case cuyo valor coincida con la expresión. O a la cláusula default si
ninguna coincide.
6 Este ejemplo usa un plain object, que veremos al nal de este tema
99
'use strict'
let y;
let x=":";
switch(x){
case(';'):
y="punto y coma";
break;
case(':'):
y="dos puntos";
break;
default:
y="caracter desconocido";
}
console.log(y); // dos puntos
'use strict'
let x='ubuntu';
let so="";
switch(x){
case('ubuntu'):
//fall through
case('debian'):
//fall through
case('fedora'):
//fall through
case('redhat'):
so='linux';
break;
case('macos'):
so="macos"
break;
default:
100
so='no soportado';
}
console.log(so);
'use strict'
function cuadrante(x,y){
let r;
switch(true){
case( x>= 0 && y>=0):
r=1;
break;
case( x< 0 && y>=0):
r=2;
break;
case( x< 0 && y<0):
r=3;
break;
case( x>= 0 && y<0):
r=4;
break;
default:
r=NaN;
}
return r;
}
console.log(cuadrante(1,-1)); // 4
while
'use strict'
let x=5;
let cadena="";
while(x>0){
--x;
cadena+="*";
}
console.log(cadena); //*****
x=5;
cadena="";
while(true){
if(x<1) break;
--x;
cadena+="*"
}
console.log(cadena); //*****
101
for
La sentencia for también es como en C y muchos otros lenguajes
'use strict'
let cadena="";
for(let i=0; i<5; ++i){
cadena+="*";
}
console.log(cadena); //*****
La primera posición es la 0
'use strict'
let x;
x="Lorem Ipsum";
102
Como hemos visto, JavaScript tiene una característica peligrosa: si in-
tentamos acceder a una propiedad inexistente de un objeto, simplemente
obtenemos undefined
Supongamos que, por error, escribamos x.lengh en vez de x.length
for (let i=0; i<x.lengh; ++i){ //½ERROR! Debería ser length, no lengh
console.log(x[i]);
}
'use strict'
let x="Lorem Ipsum";
Manipulación de cadenas
Las cadenas tienen diversos métodos que permiten su manipulación Todos
estos métodos devuelven una nueva cadena, dejando la original intacta
> 'contraseña'.toUpperCase()
'CONTRASEÑA'
> 'LoReM IPsum'.toLowerCase()
'lorem ipsum'
103
Espacios en sentido amplio, incluye tabuladores y el caracter n
de línea
> '__abc'.indexOf('abc')
2
> '__abc'.indexOf('xxx')
-1
> 'a.tar.gz'.lastIndexOf('.')
5
> '0123'.slice(0,3)
'012'
> 'abc'.slice(0,7)
'abc'
> 'abc'.slice(-5,7)
'abc'
> 'abc'.slice(3,2)
''
> 'abc'.slice(2,2)
''
104
El método split(c) trocea una cadena, usando el caracter c como
separador. Devuelve un array
> "a,b,c".split(',')
[ 'a', 'b', 'c' ]
4.12. Arrays
Arrays
En JavaScript disponemos de un tipo de objeto denominado array (lista).
Un array es un objeto donde se hace corresponder un número natural con un
valor
'use strict'
let a,b,c,d;
105
Los arrays en JavaScript tienen muchos métodos disponibles. Mostramos
algunos de los principales
'use strict'
let a,x;
a=['sota', 'caballo'];
// Truncar un array
a.length=0;
console.log(a); // []
106
slice
El método slice() devuelve una rodaja de una lista. No es destructivo
'use strict'
let a;
a=['sota', 'caballo', 'rey', 'as'];
let i = 1;
let j = 3;
console.log(a[i]) // caballo
//console.log(a.slice(,2)); // ERROR
console.log(a.slice(2)); // ['rey', 'as']
console.log(a.slice(2,)); // ['rey', 'as']
// slice no es destructivo
console.log(a); // ['sota', 'caballo', 'rey', 'as'];
splice
El método splice() devuelve una rodaja de una lista, de forma destructiva
'use strict'
let a=['sota', 'caballo', 'rey', 'as'];
let i = 1;
let n = 2;
// splice es destructivo
console.log(a); // ['sota', 'as']
107
Concatenar arrays
Los arrays disponen del método concat, que permite concatenar ese
array con otro(s) array(s)
'use strict'
let a = ['alpha', 'beta'];
let b = ['gamma', 'delta'];
let c = a.concat(b);
console.log(c); // [ 'alpha','beta','gamma','delta' ]
Al estilo C
'use strict'
let l=["a",,"c"];
for(let i=0; i<l.length; ++i){
console.log(l[i]);
}
// a undefined c
'use strict'
let l=["a",,"c"]
l.forEach(function(x){
console.log(x);
});
// a c
108
Especialmente conveniente es for-of, disponible en ECMAScript 6
'use strict'
let l=["a",,"c"]
for(let x of l){
console.log(x);
}
// a undefined c
No debemos usar for-in para recorrer un array, porque los arrays, además
de índice, pueden tener otras propiedades que también se recorrerían
'use strict'
let a,x;
a=[7, 8];
a.color='azul'
for (x in a){
console.log(x); // 0, 1, color
}
'use strict'
let a;
a=[7, 8, 9, 7];
console.log(a.indexOf(9)); // 2
console.log(a.indexOf(3)); // -1
console.log(a.lastIndexOf(7)); // 3
109
Cada objeto está compuesto por un conjunto de propiedades
Clave
Una cadena
Valor
Su declaración
'use strict'
let x={
unidades:2,
color:'verde',
tamaño:'grande',
};
console.log(x); // { unidades: 2, color: 'verde', 'tamaño': 'grande' }
console.log(x.unidades); // 2
console.log(x.precio); //undefined
'use strict'
let p={ latitud:40.3355, longitud:-3.8773 };
console.log(p.latitud); // 40.3355
console.log(p["latitud"]); // 40.3355
let clave="latitud";
console.log(p[clave]); // 40.3355
110
Podemos obtener la lista de claves de un objeto usando el método keys()
del built-in object Object
Object.keys(miObjeto)
'use strict'
let p={ latitud:40.3355, longitud:-3.8773 };
console.log(typeof(miObjeto)); //object
console.log(typeof(miLista)); //object
console.log(Array.isArray(miObjeto)); //false
console.log(Array.isArray(miLista)); //true
Una función solo devuelve 1 valor. Si necesitamos que devuelva más, po-
demos usar estos objetos
'use strict'
function f(x,y){
let r={};
r.suma=x+y;
r.producto=x*y;
return r;
};
console.log(f(2,3)); // { suma: 5, producto: 6 }
console.log(f(2,3).suma); // 5
console.log(f(2,3).producto); // 6
4.14. Excepciones
Excepciones
111
Las excepciones son similares a las de cualquier otro lenguaje
'use strict'
// Atención, ejemplo no realista
try {
throw 'xxx27';
} catch (e) {
console.log('capturada excepción ' + e);
// capturada excepción xxx27
}
try{
console.log( no_definido);
} catch (e) {
console.log("capturada excepción ",e.name,e.message);
}
//capturada excepción ReferenceError no_definido is not defined
112
Hay 7 nombres de error
Error
Unspecied Error
EvalError
RangeError
ReferenceError
SyntaxError
TypeError
URIError
'use strict'
// Atención, ejemplo no realista
try{
throw new RangeError('Problema en módulo xxx28');
} catch (e) {
console.log('capturada excepción ',e.name,e.message);
// capturada excepción RangeError Problema en módulo xxx28
}
½Muy importante!
113
En situaciones reales, no tiene ningún sentido que la misma función
lance una excepción y luego la capture.
4.15. Referencias
Referencias
Speaking JavaScript. An In-Depth Guide for Programmers
Axel Rauschmayer. O'Reilly Media, 2014
https://learning.oreilly.com/library/view/speaking-javascript/9781449365028
https://learning.oreilly.com/library/view/javascript-the-definitive/9781491952016
114
5. DOM: Document Objecto Model
8 Este uso aparece en los años 1950, cuando los helados con sabor vainilla (articial),
se convierten en los más habituales por ser los más baratos
115
En cualquier navegador web, a menos que sea muy antiguo
116
Funcionalidad que realmente mejora la experiencia de usuario:
Validación de formularios
Formularios mejorados
Ejemplos
HTML SVG
https://github.com/d3/d3/wiki/Gallery
...
117
Ejecución de un programa Javascript
La ejecución de un programa JavaScript en el navegador tiene dos partes
1. Ejecución secuencial
Por cada atributo del elemento HTML, hay una propiedad en el ele-
mento JavaScript
Objetos Globales
En el DOM hay dos objetos globales muy importantes. Están predenidos,
siempre están presentes en cualquier documento.
1. Window
2. document
Pero además
118
En otras palabras, todos los scripts de una ventana o pestaña comparten
el mismo espacio de nombres
Objeto Window
El código JavaScript que se ejecuta en el navegador tiene un objeto
global llamado Window
Hay uno por cada ventana (o pestaña) del navegador, compartido por
todos los scripts y todos los módulos (pero no los WebWorkers ) 10
Objeto document
Cuando el navegador procesa el HTML, crea un objeto document
Es el objeto principal del DOM, en él se insertan todos los objetos
Element y todos los nodos de texto
5.2. Eventos
Eventos
Como hemos visto, una vez cargado y procesado el HTML, el programa
JavaScript dentro del navegador entra en la fase dirigida por eventos
¾Qué pasa?
event type. También llamado nombre. Es una cadena de texto que es-
pecica de qué evento se trata. P.e. click, mouseover, keydown, etc
10 En node.js este objeto se llama global. En los WebWorkers este objeto se llama Wor-
kerGlobalScope
119
¾Dónde pasa?
¾Cómo responder?
event object. Objeto con detalles sobre el evento: coordenadas del ratón,
tecla pulsada, etc
El manejador
120
<button id="boton01">Dame un clic</button>
<script>
'use strict'
function manej_boton01() {
console.log("Clic recibido.");
}
let b = document.querySelector("#boton01");
// Atención a la almohadilla, es imprescindible
b.addEventListener("click", manej_boton01);
// Atajo para ver los log: F12
// Atajo alternativo: Ctr Shift I
</script>
http://ortuno.es/hola_js_01.html
Todo manejador recibe un objeto event con los detalles del evento
let b = document.querySelector("#boton01");
b.addEventListener("click", manej_boton01);
</script>
http://ortuno.es/hola_js_02.html
Depuración
Para depurar un programa JavaScript en el navegador
121
Escribiremos trazas con console.log()
1. Un div tiene una tabla que tiene un botón que tiene una imagen
Técnicas obsoletas
En código, recetas y libros antiguos podremos encontrar selección de ele-
mentos con métodos como
document.getElementById
document.getElementsByName
document.getElementsByTagName(
document.getElementsByClassName
document.images
document.forms
document.links
... etc
122
5.3. Contenido de un elemento
Texto de un elemento
Para acceder al contenido de un elemento en texto plano, cada objeto
element tiene la propiedad textContent, que podemos leer o escribir
<button id="boton01">Registrar hora </button>
<p id="parrafo01">--</p>
<script>
'use strict'
function manej_boton01(event) {
let parrafo01 = document.querySelector("#parrafo01");
let fecha = new Date();
parrafo01.textContent = fecha;
}
let boton01 = document.querySelector("#boton01");
boton01.addEventListener("click", manej_boton01);
</script>
http://ortuno.es/texto.html
Atributos inexistentes
Recuerda esta característica muy desafortunada de JavaScript
123
Según vayas adquiriendo experiencia, traza solo aquellos aspectos que
te parezca que tengan especial relevancia o dicultad
function manej_boton01(event) {
console.log("manej_boton01");
let parrafo01 = document.querySelector("#parrafo01");
console.log(parrafo01);
let fecha = new Date();
console.log("Valor de la fecha:"+fecha);
parrafo01.textContent = fecha;
}
let boton01 = document.querySelector("#boton01");
console.log(boton01);
boton01.addEventListener("click", manej_boton01);
http://ortuno.es/texto.trazas.html
console.log(v_out);
let v_out_div = document.querySelector("#v_out");
v_out_div.textContent = v_out;
}
http://ortuno.es/calculo_mal.html
124
El ejemplo anterior en principio funciona, pero
Enfoque correcto:
<body>
<script>
let x = 0; // Variable global a todo el documento
</script>
<div id="display01"></div>
<br>
<button id="boton01">Suma 1</button>
<button id="boton02">Suma 5</button>
<script>
'use strict'
function actualiza_valor() {
let div = document.querySelector("#display01");
div.textContent = x;
}
</script>
125
<script>
use 'strict'
function manej_boton01() {
x = x + 1;
actualiza_valor();
}
function manej_boton02() {
x = x + 5;
actualiza_valor();
}
http://ortuno.es/globales.html
Las variables globales exigen mucha atención, son muy peligrosas. Al-
gunas metodologías las prohíben, el resto, exige minimizarlas
11 Sería mejor hacerlo mediante cierres (closures), pero es algo más complejo y no lo
trataremos aquí
126
document.createElement()
Recibe como argumento una cadena con el nombre de un tipo de
elemento HTML (p, img, table, etc)
<body>
<button id="boton01">Registrar hora </button>
<div id="div01">--</div>
<script>
'use strict'
function manej_boton01(event){
let div01 = document.querySelector("#div01");
let fecha = new Date();
let parrafo = document.createElement("p");
parrafo.textContent = fecha;
div01.append(parrafo);
}
let boton01 = document.querySelector("#boton01");
boton01.addEventListener("click", manej_boton01);
</script>
</body>
http://ortuno.es/nuevo_p.html
Es una propiedad
parrafo.textContent = fecha;
append
Es un método
div01.append(parrafo);
Añade cualquier cosa al elemento: texto, una la, una imagen, un en-
lace...
En ocasiones puede resultar equivalente usar uno o usar otro. P.e. meter
texto en un párrafo vacio o en un texto vacio
127
<button id="boton01">append</button>
<button id="boton02">textContent</button>
<br>
<div id="div01"></>
<script>
'use strict'
function usa_append(event){
let div = document.querySelector("#div01");
div.append("hola");
}
function usa_textContent(event){
let div = document.querySelector("#div01");
div.textContent = "hola";
}
http://ortuno.es/append_textContent.html
<table id=tabla_horas>
<tr>
<th>Hora del clic</th>
</tr>
</table>
<button id="boton01">Registrar hora </button>
<script>
'use strict'
function manej_boton01(event){
// Seleccionamos la tabla
let tabla_horas = document.querySelector("#tabla_horas");
http://ortuno.es/nueva_fila.html
128
O dos celdas en una la
let contador_clics = 0;
function manej_boton01(event){
let tabla_horas = document.querySelector("#tabla_horas");
contador_clics = contador_clics + 1;
let tr = document.createElement("tr"); // Creamos fila
http://ortuno.es/nueva_fila_celdas.html
Añadir contenido
Una vez seleccionado un elemento o elementos mediante un selector, in-
sertarlo en diferentes posiciones
append()
prepend()
after()
before()
129
before() escribe inmediatamente antes
replacewith()
Reemplaza la selección
remove()
Borra la selección
por cada atributo en el elemento HTML hay una propiedad en el objeto ele-
ment correspondiente en JavaScript, que casi siempre tiene el mismo nombre
<img src=...>
(o cualquier otra referencia a un chero)
images/gato.jpg
Un trayecto que empieza por barra es absoluto, cuelga del directorio
raiz
/images/gato.jpg
130
Un trayecto absoluto que incluye el directorio home del usuario como
una cadena literal, es un error serio
/home/alumnos/jperez/images/gato.jpg
http://ortuno.es/crea_imagen.html
131
Naturalmente, será necesario que el elemento tenga un atributo id, que
se lo habremos añadido o bien de forma estática (en el HTML) o bien
de forma dinámica (programándolo en JavaScript)
Le añadimos un id
Le añadimos un manejador para que cada vez que la imagen reciba un
click, dispare cierta función
let contador_gatos = 0;
function crear_gato(event){
let div01 = document.querySelector("#div01");
// Añadimos un id a la imagen
contador_gatos = contador_gatos + 1;
let id = "gato_" + String(contador_gatos) ;
img.id = id;
http://ortuno.es/identifica_imagen.html
132
<script>
'use strict'
pon_gato(); // Empezamos poniendo una imagen para que no quede
// en la página una foto vacía, incorrecta
function pon_gato(event){
let img = document.querySelector("#foto");
img.src = "images/gato.jpg";
img.alt = "Gato común europeo de color naranja";
img.width="300";
}
function pon_periquito(event){
let img = document.querySelector("#foto");
img.src = "images/periquito.jpg";
img.alt = "Periquito azul";
img.width="300";
}
</script>
<script>
let boton01 = document.querySelector("#boton01");
boton01.addEventListener("click", pon_gato);
http://ortuno.es/cambia_imagen.html
Crear una regla CSS que modique el atributo para cierta clase
12
Quitar y poner la clase
<style>
.oculto {
display: none;
}
</style>
12 De la misma forma que en un procesador de texto podemos modicar el formato de un
párrafo directamente, pero en general es preferible asignar un estilo al párrafo, y modicar
el formato del estilo
133
<button id="boton01">Ver foto</button>
<button id="boton02">Quitar foto</button>
<div id="marco_foto" class="oculto">
<img src="images/plaza_espana.jpg" alt="Plaza de España, Madrid">
</div>
<script>
'use strict'
function quita_clase() {
console.log("quita_clase");
let marco = document.querySelector('#marco_foto');
marco.classList.remove("oculto");
};
function pon_clase() {
console.log("pon_clase");
let marco = document.querySelector('#marco_foto');
marco.classList.add("oculto");
};
http://ortuno.es/quita_pon_01.html
y esto
<div id="marco_foto">
<img src="images/plaza_espana.jpg" alt="Plaza de España, Madrid">
</div>
134
Como hemos visto, el atributo class se corresponde con la propiedad
JavaScript className, por ser class una palabra reservada
Esto es, de los valores del atributo class, troceados por espacios
Con el código
marco.classList.add("oculto");
Con el código
marco.classList.remove("oculto");
<div id="marco_foto">
135
Con el método toggle (alternar) de la lista de atributos
function alterna_clase() {
let marco = document.querySelector('#marco_foto');
marco.classList.toggle("oculto");
};
http://ortuno.es/quita_pon_02.html
http://ortuno.es/elimina.html
136
Hay muchas formas de seleccionar una serie de elementos:
Todos los que tengan cierto atributo, con cierto valor, p.e. el chero de
una imagen
...
display / visibility
Para hacer un elemento invisible, puedo usar
display
Oculta el elemento y reposiciona el resto
visibility
Oculta el elemento, sin reposicionar el resto
<style>
.sin_display {
display: none;
}
.invisible {
visibility: hidden;
}
</style>
...
<script>
for (let gato of gatos){
if (usa_display)
gato.classList.toggle("sin_display");
else
gato.classList.toggle("invisible");
}
</script>
http://ortuno.es/selecciona.html
137
Modicar el CSS directamente
Para modicar los atributos css, normalmente es preferible vincularlos a
una clase y poner y quitar clases, como acabamos de ver
Con una modicación: los atributos CSS suelen incluir guiones, que no
son válidos en JavaScript (se interpretarían como el operador de resta).
13
Así que hay que convertir a notaciónDromedario
function manej_boton01(event) {
let p01 = document.querySelector("#span01");
p01.style.backgroundColor="LightSkyBlue";
}
function manej_boton02(event) {
let p01 = document.querySelector("#span01");
p01.style.backgroundColor="LightSalmon";
}
http://ortuno.es/css_js.html
mouseout
Se recibe cuando el ratón abandona el elemento o cualquiera de sus
descendentes
mouseleave
Se recibe cuando el ratón abandona el elemento seleccionado
13 En español tenemos la NotaciónCamello y la notaciónDromedario, pero en inglés es
diferente: PascalCase, camelCase
138
Eventos mouseout, mouseleave
Podemos observar la diferencia entre mouseout y mouseleave en esta de-
mo. No usa JavaScript contemporáneo sino jQuery, pero podemos seguir el
funcionamiento general
https://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_event_mouseleave_mouseout
Un primer div de clase over que contiene un texto que contiene un span
139
Para incrementar los contadores, captura el valor que hay dentro del
span y le suma 1. Lo hace en jQuery, en JavaScript contemporáneo
usaríamos textContent
El diseño que preferimos aquí emplearía una variable distinta para estos
contadores. El span se limitaría a copiar esa variable
function manej01(event) {
event.target.classList.add("destacado");
}
function manej02(event) {
event.target.classList.remove("destacado");
}
http://ortuno.es/eventos_01.html
function crea_parrafos(){
for(let i=0; i<3; ++i){
let div01 = document.querySelector("#div01");
let p = document.createElement("p");
p.textContent = "Lorem ipsum dolor sit amet";
p.addEventListener("mouseover", manej01);
p.addEventListener("mouseout", manej02);
div01.append(p);
}
}
http://ortuno.es/eventos_02.html
140
Recuerda que un evento que llega a un elemento, también llega a todos
sus antecesores. Podemos:
<div id=div01>
<p id=p01>Lorem ipsum dolor sit amet.</p>
<p id=p02>Lorem ipsum dolor sit amet.</p>
<p id=p03>Lorem ipsum dolor sit amet.</p>
</div>
<script>
function manej01(event) {
event.target.classList.add("destacado");
}
function manej02(event) {
event.target.classList.remove("destacado");
}
5.10. Formularios
Formularios (1)
Para acceder al valor de un formulario
141
Formularios (2)
Para consultar el estado de un radiobutton o un checkbox, usamos un
selector como
input[name=figura]:checked
Captura todos los input que contengan el atributo name con el valor
gura
El selector :checked captura todos los <input> activados
http://ortuno.es/formulario_02.html
Validación de un formulario
Validar un formulario consiste en comprobar que el usuario ha rellenado
los campos con valores adecuados. Esto podemos hacerlo
let contrasenia_minima = 8;
function valida_contrasenia(contrasenia){
let texto;
if (contrasenia.length >= contrasenia_minima) {
texto = "Contraseña aceptable";
} else {
texto = "Contraseña muy corta";
}
142
return texto;
}
function manej01(event) {
let contrasenia = document.querySelector("#contrasenia").value;
let texto_validacion = valida_contrasenia(contrasenia);
http://ortuno.es/validacion_01.html
Change
Fin de edición del input
keyup
Pulsación de teclado (liberación de la tecla pulsada)
paste
Pegado desde el portapapeles
mouseup
Pulsación del botón del ratón (n de la pulsación)
function manej01(event) {
let contrasenia = document.querySelector("#contrasenia").value;
let texto_validacion = valida_contrasenia(contrasenia);
http://ortuno.es/validacion_02.html
143
6. JavaScript(ii)
let k = 10;
let x;
http://ortuno.es/ej_random.js
144
'use strict'
// Tiempo transcurrido
console.log(d2-d1); // 1027 (milisegundos)
'use strict'
let intervalo = 0;
let d1 = new Date(intervalo);
console.log(intervalo, typeof(intervalo));
// 0 'number'
console.log(d1, typeof(d1));
// 1970-01-01T00:00:00.000Z 'object'
145
'use strict'
console.log(intervalo1); // 0
console.log(intervalo2); // 86400000
let d1 = new Date(intervalo1);
console.log(d1); // 1970-01-01T00:00:00.000Z
let d2 = new Date(intervalo2);
console.log(d2); // 1970-01-02T00:00:00.000Z
Si necesitamos construir un date a partir del año, mes, día, etc, podemos
pasar estos argumentos al constructor
146
console.log(d.getFullYear()); // 2017
console.log(d.getMonth()); // 8 (septiembre)
console.log(d.getDate()); // 1
console.log(d.getDay()); //5 (viernes)
console.log(d.getHours()); // 9 hora española
console.log(d.getMinutes()); // 0
console.log(d.getSeconds()); // 0
console.log(d.getMilliseconds()); //
'use strict'
let d1,d2;
// las 9 y 10
d2=new Date(2017, 8, 1, 9, 10, 0);
'use strict'
let d1,d2,s, ms_año, edad;
147
Hora Unix a partir de Date
'use strict'
'use strict'
let d1 = new Date(2024, 2, 18, 10, 0, 0);
let d2 = new Date(2024, 2, 18, 10, 30, 0);
console.log(d1); // 2024-03-18T09:00:00.000Z
console.log(d2); // 2024-03-18T09:30:00.000Z
let intervalo = d2 - d1
console.log(typeof(intervalo), intervalo);
// number 1800000 (180000 ms = 1800 s = 30 m)
let d3 = d2 + intervalo
console.log(d3)
// Mon Mar 18 2024 10:30:00 GMT+0100 (Central European Standard Time)1800000
½Pero no!. Lo que hace es concatenar la cadena con la hora y la cadena con
los milisegudos
'use strict'
let d2 = new Date(2024, 2, 18, 10, 30, 0);
console.log(d2); // 2024-03-18T09:30:00.000Z
148
6.3. Módulos
Módulos
Un módulo es
CommonJS
Para Node.js
RequireJS
Para el navegador
En el navegador, tanto los módulos como los cheros que usan los mó-
dulos, tienen que tener extensión .js
En node.js, tanto los módulos como los cheros que usan los módulos,
tienen que tener extensión .mjs
Una solución es usar los enlaces simbólicos de Unix (Linux, macOS). O
los accesos directos de Windows
149
2. Para el navegador, creamos enlaces simbólicos .js
ln -s modulo.mjs modulo.js
ln -s programa.mjs programa.js
Si lo hacemos al revés (el chero original con .js y enlace con .mjs), no
funciona. Node.js toma el js, dando error
modulo.mjs
programa.mjs
'use strict'
import * as modulo from './modulo';
console.log(modulo.f());
console.log(modulo.g());
'use strict'
import { f, g } from './modulo';
console.log(f());
console.log(g());
Observaciones
150
Para especicar la ubicación del módulo, es imprescindible indicar el
path relativo con ./
Si queremos que el código funcione tanto en el navegador como en
node.js, no ponemos extensión
.mjs
en node.js, podemos poner extensión
Uso en node.js
En las versiones actuales de node.js, el soporte para los módulos es
experimental, hay que añadir un ag para interpretarlo
Uso en el navegador
<!DOCTYPE html>
<html lang="es-ES">
<head>
<meta charset="utf-8">
<title>Probando modulos</title>
</head>
<body>
<script type="module" src="programa.js"> </script>
</body>
</html>
http://ortuno.es/probando_modulos.html
151
Un script que usa módulos, integrado en una página web solo puede eje-
cutarse cuando la página ha sido cargada desde un servidor web, no cuando
ha sido leída de un chero local
Googlea web server for Chrome. Es una app para el navegador Chrome.
Instálala
Ejemplo:
6.4. TypeScript
TypeScript
Como hemos visto, JavaScript tiene
152
Muchos inconvenientes.
Forman parte de la esencia del lenguaje, para evitarlos habría que usar
un lenguaje diferente
153
Problemas de la herencia (1)
Código yo-yo
Por muy bien que se diseñe una jerarquía de clases, en dominios me-
dianamente complejos acaban apareciendo casos no previstos que no
encajan en la taxonomía inicial
Herencia múltiple
Arquitectura frágil
154
Metáfora.
Una vez que se conoce su uso resulta sencillo, pero su curva de apren-
dizaje es pronunciada
Lambdas
Cierres
Funciones echa
Prototipos
Factoria de objetos
155
Enlaces sobre POO basada en prototipos
Composition over Inheritance
Eric Elliott
http://tinyurl.com/zbtjruf
http://proquest.safaribooksonline.com/book/programming/javascript/9781491950289
http://proquest.safaribooksonline.com/book/programming/javascript/9781457185304
Los argumentos principales por los que se acepta este paso atrás son
156
Clases
Denimos clases con la palabra reservada class, el nombre de la clase
y entre llaves, sus propiedades
Para crear una clase heredera de otra: class Hija extends Madre{ ....}
Para llamar a un método de la clase padre, se usa la palabra reservada
super
'use strict'
class Circunferencia{
constructor(x,y,r){
this.x=x;
this.y=y;
this.r=r;
}
aCadena(){
return '('+this.x+','+this.y+','+this.r+')';
}
}
class Circulo extends Circunferencia{
constructor(x,y,r,color){
super(x,y,r);
this.color=color;
}
aCadena(){
return super.aCadena()+ " color:"+ this.color;
}
}
let a=new Circunferencia(2,2,1);
console.log(a.aCadena()); // (2,2,1)
let b=new Circulo(2,2,1,"azul");
console.log(b.aCadena()); // (2,2,1) color: azul
157
Métodos
Para declarar los métodos de una clase no es necesario usar la palabra
reservada function
Las clases tienen tres tipos de métodos.
constructor()
Es un método especial para crear inicializar los objetos de esta clase
Cuando procese 2 o más objetos, sin que uno tenga más relevancia
que otro
'use strict'
class Circunferencia{
constructor(x,y,r){
this.x=x;
this.y=x;
this.r=r;
}
aCadena(){
return '('+this.x+','+this.y+','+this.r+')';
}
static distanciaCentros( a, b){
return Math.sqrt(
Math.pow(a.x-b.x, 2) + Math.pow(a.y-b.y,
2));
}
longitud(){
return 2*Math.PI*this.r;
}
}
158
Enlaces sobre clases en JavaScript
MDN Web Docs. Classes
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
http://exploringjs.com/es6/ch_classes.html#sec_overview-classes
159
7. APIs de HTML5
Web Storage
Web Workers
Geolocation
Canvas
Web Messaging
https://en.wikipedia.org/wiki/HTML5#New_APIs
160
Por todo ello
sessionStorage
Un diccionario que dura tanto como la sesión. Se borra al cerrar el
navegador
localStorage
Un diccionario persistente, el diccionario se mantiene aunque se cierre
el navegador. Solo se borra si el usuario o la página lo borran explíci-
tamente
Almacenamiento de un valor
localStorage.setItem(clave) = valor;
sesionStorage.setItem(clave) = valor;
Recomendación:
161
Recuperación de un valor
localStorage.getItem(clave);
sesionStorage.getItem(clave);
Borrado de valores
localStorage.removeItem(clave)
sesionStorage.removeItem(clave)
Borran la clave
'use strict'
let nombreUsuario = localStorage.getItem('nombreUsuario');
if (!nombreUsuario) {
let input= prompt("¾Cómo te llamas?");
localStorage.setItem('nombreUsuario',input);
} else {
alert("Hola " + nombreUsuario);
}
for (let clave in localStorage) {
let valor = localStorage[clave];
console.log(clave+": "+valor)
}
http://ortuno.es/localStorage.html
162
let clave = 'nombreUsuario';
let valor=localStorage.getItem(clave);
if (valor){
localStorage.removeItem(clave);
alert(clave+ ' valía '+valor+ '. Ahora lo he borrado');
}else{
alert(clave+" no definido");
};
http://ortuno.es/localStorage2.html
Referencias
https://en.wikipedia.org/wiki/Web_storage
https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API
Se crea como instancia del objeto/la función Worker(), que recibe como
argumento el nombre del script
163
El siguiente ejemplo calcula dos números aleatorios, y cuando coinciden,
envía un mensaje
'use strict'
function random(x){
return Math.floor((Math.random() * x) + 1);
}
let tamanio=1000000;
let x,y;
let c=100;
while (c>0){
x=random(tamanio);
y=random(tamanio);
if (x===y) {
postMessage(x);
c-=1;
}
}
http://ortuno.es/web_worker.js.txt
http://ortuno.es/web_worker.html
7.4. Geolocation
Geolocation
Los navegadores modernos pueden conocer, si el usuario lo permite, su
ubicación geográca
Posiblemente el más preciso es Google Chrome
164
En conexiones cableadas, obtiene información a partir de la dirección
IP
En conexiones WiFi
Con los coches que capturan datos para Google Maps. (Aunque esto le
causó problemas legales)
let options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
};
function success(pos) {
let x = pos.coords;
let mensaje = 'Posición actual\n';
mensaje += 'Latitud :' + x.latitude;
165
mensaje += '\nLongitud :' + x.longitude;
mensaje += '\nPrecisión :' + x.accuracy + " metros";
alert(mensaje);
}
function error(err) {
console.warn(`ERROR(${err.code}): ${err.message}`);
};
navigator.geolocation.getCurrentPosition(success, error, options);
http://ortuno.es/geoloc.html
166
8. Json
Value
Fuente:json.org
167
Number
Fuente:json.org
String
Fuente:json.org
168
Array
Fuente:json.org
Objetos
Fuente:json.org
Ejemplos correctos
"hola, mundo"
4243.12
-947e-5
null
[1,2,3,4]
169
[1, "azul", [1,2,3]]
[
1,
"azul",
[
1,
2,
3
]
]
[
"sota",
"caballo",
"rey"
]
{ "nombre":"Juan", "apellido":"Pérez"}
{
"nombre": "Juan",
"notas": [
5.5,
7.2,
6.1
]
}
170
Ejemplos incorrectos
True
'hola, mundo'
{"hola,mundo"}
{1:"uno", 2:"dos"}
'use strict'
let lista=[ "sota", "caballo", "rey" ];
console.log(typeof(lista),lista);
// object ["sota","caballo","rey"]
let cadena=JSON.stringify(lista);
console.log(typeof(cadena),cadena);
// string ["sota","caballo","rey"]
'use strict'
let cadena='{ "nombre":"redes", "curso":1,
"horario":["L1500", "X1700"] }'
console.log(typeof(cadena),cadena);
// string
//{"nombre":"redes", "curso":1, "horario":["L1500", "X1700"] }
let objeto=JSON.parse(cadena);
console.log(typeof(objeto),objeto);
// object
//{ nombre: 'redes', curso: 1, horario: [ 'L1500', 'X1700' ] }
171
9. AJAX
Funcionamiento de Ajax
1. El usuario solicita una URL desde su navegador
4. El script hace peticiones HTTP asíncronas a una URI del servidor, sin
que el usuario intervenga. El servidor suele ser RESTful
Same-origin policy
Same-origin policy es una norma que aparece en Netscape 2 (año 1995),
que se ha convertido en un estándar. Consiste en que el código JavaScript
solo puede acceder a datos que provengan del mismo origen desde el que se
ha cargado el script
Ejemplo
172
Esta página web puede tener código JavaScript que acceda a datos que
estén en molamazo.com, pero solamente en este sitio
No puede acceder a datos en bancofuenla.es
bancofuenla
De lo contrario, una vez que el usuario se autentica en
con una página de bancofuenla, un script malicioso en molamazo
podría acceder a información sensible en bancofuenla
9.2. JSONP
JSOP
JSONP ( JSON with padding, JSON con relleno ) es una técnica que per-
mite que una página web obtenga datos desde un sitio web distinto al suyo,
sin vulnerar la same-origin policy
Es un protocolo del año 2005, soluciona el problema pero no es es-
pecialmente elegante. También tiene algunos problemas de seguridad
potenciales
173
Si bancofuenla accede a enviar "f(3)" como dato JSON, sabe
que esta información podría ser usada por un script de cualquier
otro sitio, p.e. molamazo. Por tanto, nunca enviará de este modo
información sensible
bancofuenla.es/divisas.html?par=USDEUR&fecha=hoy&callback=procesaDivisas
procesaDivisas(0.865)
procesaDivisas() será una función en el script cliente, que tratará el
dato (0.865)
Devuelve:
174
9.3. Ejemplo: cambio de divisas
El siguiente ejemplo llama a http://fixer.io, un servicio que ofrece
tipos de cambio de divisas
Otra solución para los sitios sin soporte de JSONP (que son muchos),
sería un proxy en el mismo sitio web que sirve el HTML
$(document).ready(function() {
let urlServicio = 'http://data.fixer.io/latest';
peticion = $.ajax({
url: urlServicio,
data: {
access_key: "xxxxxx",
symbols: "USD, GBP"
}
})
peticion.done(manejaRespuesta);
peticion.fail(manejaError);
function manejaRespuesta(json) {
$("#div01").text(JSON.stringify(json));
};
function manejaError(jqXHR) {
$("#div01").text("Error: " + jqXHR.status);
};
});
Cambio de divisas
Cada divisa tiene un código ISO 4217, que es un identicador de 3
letras mayúsculas. Por ejemplo USD (United States Dollar) para el
dólar, EUR para el euro, GBP para la libra esterlina, etc
175
Ejemplo EURUSD = 1.13
setInterval
Para que la consulta Ajax se repita periódicamente, podemos usar la
función setInterval()
Recibe
setInterval(function() {
miTexto=actualizaTexto();
$("#p01").text(miTexto);
},
60000
);
176
10. APIs de ejemplo
10.1. YouTube
YouTube
Insertar un reproductor de vídeo de YouTube en JavaScript es muy sen-
cillo
event.target.playVideo()
http://ortuno.es/youtube.html
177
10.2. OpenStreetMap
OpenStreeMap
OpenStreetMap (OSM) es un proyecto que tiene como objetivo crear un
mapa del mundo editable y libre
<script src="https://unpkg.com/[email protected]/dist/leaflet.js">
178
En nuestro HTML denimos un DIV donde irá el mapa. Es necesario
que tenga denido un atributo CSS height con la altura
<style>
#id_mapa {
height: 400px;
}
</style>
...
<div id="id_mapa"></div>
$(document).ready(function() {
let latitud=40.417; //coordenada y
let longitud=-3.703; //coordenada x
let zoom=16;
let mi_mapa = L.map('id_mapa').setView([latitud, longitud], zoom);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution:\
'© <a href="http://osm.org/copyright">OpenStreetMap</a>'
}).addTo(mi_mapa);
});
http://ortuno.es/openstreet.html
L.marker(<COORDENADAS>).addTo(<OBJETO MAP)
Podemos añadir mensajes emergentes de tipo popup, con el método
.bindPopup de un marcador
179
let mi_marcador = L.marker(coord_labIII).addTo(mi_mapa);
mi_marcador.bindPopup("Laboratorios III").openPopup();
http://ortuno.es/openstreet2.html
180
11. Express
Basado en Node.js
11.2. Instalación
Instalación de Express
Para usar Express.js necesitamos una versión reciente de node.js. Con
Ubuntu 20.04 se distribuye node.js v10, que no cumple este requisito
node -v
cd
curl -sL https://deb.nodesource.com/setup_16.x | sudo bash -
sudo apt-get install -y nodejs
181
11.3. Diseño de las URL
Diseño de las URL
El interface de una aplicación (las URL que usarán cliente y servidor) en
Express.js o en cualquier otra herramienta, debe seguir los mismos princios de
calidad. Una URL bien diseñada debería permanecer un número indenido
de años ( toda la vida ), sin importar que cambien las tecnologías: framework,
lenguaje, sistema operativo etc. Para ello:
http://www.ejemplo.com/busqueda
Mal:
http://www.ejemplo.com/busqueda.php
Evitar palabras irrelevantes. Una URL debe ser corta, cada palabra
debe tener signicado. P.e. si todas las URL empiezan por /home/, esa
palabra sobra
Bien:
http://www.ejemplo.com/busqueda
Mal:
http://www.ejemplo.com/home/app/auto/busqueda
Bien:
http://www.ejemplo.com/user-id/:user-id/app-id/:app-id
http://www.ejemplo.com/userId/:userId/appId/:appId
Mal:
http://www.ejemplo.com/userId/:userId/app-id/:app-id
Bien:
http://www.ejemplo.com/spain
Mal:
http://www.ejemplo.com/españa
182
11.4. API REST
APIs REST con Express.js
Con Express.js podemos preparar de forma muy sencilla servicios web
con interface REST / ROA
http://ortuno.es/rest.pdf
Las más habituales son las peticiones GET: el cliente web solicita un
recurso al servidor, indicando su URL. Normalmente será un chero
generado dinámicamente (por una aplicación)
node api_rest.js
events.js:174
throw er; // Unhandled 'error' event
183
Objeto app
Las dos primeras líneas de un programa en express suelen ser
app.get() app.put()
Esto es algo normal en JavaScript pero raro en otros lenguajes: una fun-
ción es un caso particular de objeto, que a su vez puede tener métodos
Routing
Una vez listo el objeto app, nos ocupamos del routing, esto es, para
cada petición del cliente, indicar qué respuesta se le dará
Con los métodos get, put, post, delete indicamos qué hacer con las
peticiones GET, PUT, POST, DELETE
1. req
Objeto con todos los detalles de la petición ( request )
2. res
Objeto con todos los detalles de la respuesta ( response )
184
res.send() permite responder texto, indicando previamente la
codicación con res.type()
res.json() seponde al cliente un objeto json
Parámetros
Podemos usar parámetros en la dirección: segmentos de la URL que cap-
turan los valores especicados en esa posición. Se indican anteponiendo el
carácter dos puntos. Los parámetros se guardan en el objeto params del ob-
jeto req. Ejemplo:
app.get('/api/coords/:x/:y', (req, res) => {
let x = req.params.x
let y = req.params.y
res.type('text/plain; charset=utf-8');
res.send('Me has pedido las coordenadas '+ x + ' ' + y);
})
/user/:userId/subject/:subjectId
Peticiones PUT
Para acceder al cuerpo de una petición PUT, ejecutamos app.use(express.json())
14
. El método use permite añadir capas de middleware, esto es, código inter-
medio que procesa todas las peticiones
app.use(express.json());
[...]
app.put('/api/add',(req,res) => {
console.log('Me has enviado este objeto:');
console.log(req.body);
res.json(req.body);
});
185
El cuerpo de la petición está disponible en req.body
Será un objeto JSON (no un valor cualquiera sino un objeto: una se-
cuencia de pares clave-valor, entre llaves)
postman
Para probar las peticiones PUT, necesitamos una herramienta como
postman
Lo podemos instalar con
Pulsamos send
Errores
Despues del routing de las peticiones previstas, añadimos los manejadores
de los errores. Es importante hacerlo en este orden, para que se ejecuten
solamente cuando no encaje ninguna ruta especicada previamente
186
// Status Code 404
app.use((req, res) => {
res.type('text/plain');
res.status(404);
res.send('404 - Not Found');
})
Error en el servidor que tal vez no sea permanente, como fallo no pre-
visto en un chero o en la base de datos. Status code 500
187
Método listen()
Una vez congurado el routing(), ejecutamos app.listen() pasando dos
argumentos
[...]
app.use(express.json());
// middleware necesario para procesar las peticiones
// POST que incluyan un cuerpo json
188
app.get('/api/carta/:id', (req, res) => {
let id = req.params.id
res.type('text/plain; charset=utf-8');
res.send('Me has pedido la carta '+id);
})
app.put('/api/add',(req,res) => {
console.log('Me has enviado este objeto:');
console.log(req.body);
res.json(req.body);
});
http://ortuno.es/api_rest.js.html
189
Aunque el propósito principal de Express.js es servir páginas web gene-
radas dinámicamente, en ocasiones necesitaremos servir cheros estáti-
cos, esto es, páginas web que se correspondan con cheros en el servidor
tal cual
Para esto, es fundamental tener claro qué signica directorio raiz de un
sitio web, sin confundirlo con el directorio raiz del sistema de cheros
(disco duro) del ordenador que sirve el web
Ejemplo 1
Si el servidor web está en el puerto 3000 de localhost y dir_raiz vale
/home/jperez/www/site01
/home/jperez/www/site01/holamundo.html
localhost:3000/holamundo.html
Observa que el nombre del directorio raiz no forma parte del path que
debe pedir el cliente web
190
Ejemplo 2
Si el servidor está en
localhost:3000
y dir_raiz vale
/home/jperez/www
/home/jperez/www/site01/holamundo.html
localhost:3000/site01/holamundo.html
$HOME
Esta sintaxis es válida en la shell de linux, pero en ningún otro entorno
~/
Esta sintaxis es válida en la shell de linux y en algunas librerías de algu-
nos lenguajes, pero raramente se puede escribir tal cual en un lenguaje
de programación
~/www/site01
Escribiríamos
191
Esto generará el directorio que corresponda a nuestro usuario, nuestra
máquina y nuestro sistema operativo
P.e. una cuenta de nuestro laboratorio, de nuestra máquina Linux o nues-
tra máquina macOS podría ser, respectivamente:
/home/alumnos/agarcia/www/site01
/home/jperez/www/site01
/Users/Ana
Ya que
Pero verás muchos libros y tutoriales que usan trayectos relativos, p.e
app.use(express.static('public');
Para servir los cheros estáticos de un directorio, tal cual, basta con
192
app.use(express.static(dir_raiz))
app.use(express.static(dir_public))
app.use(express.static(dir_js))
app.use(express.static(dir_raiz))
// Sirve todos los ficheros del directorio raiz
http://ortuno.es/estaticos01.js.html
app.use(express.static(dir_raiz))
// Sirve todos los ficheros del directorio raiz
http://ortuno.es/estaticos02.js.html
193
12. Clientes REST en JavaScript
Same-origin policy
Same-origin policy es una norma que aparece en Netscape 2 (año 1995),
que se ha convertido en un estándar. Consiste en que el código JavaScript
solo puede acceder a datos que provengan del mismo origen desde el que se
ha cargado el script
Ejemplo
194
Figura 1: Same-Origin Policy
195
En ocasiones la same-origin policy resulta demasiado estricta y se requie-
ren de técnicas que permitan, con el control adecuado, que un cliente haga
peticiones a ciertos orígenes distintos
JSONP (JSON with padding, JSON con relleno). Protocolo del año
2005. Obsoleto
Aquí no lo veremos cómo aplicarlos, así que nuestros clientes REST estarán
obligados a consultar con un servidor REST en el mismo origen (lo que en
general es la opción preferible, la más sencilla y segura)
12.2. Promesas
Promesas
El uso de promesas es una técnica de programación concurrente disponible
en lenguajes de programación como Java, JavaScript 6, C++, C#, Scala y
muchos otros
196
En ECMAScript 2017 están disponible mediante las palabras reserva-
das async await (aunque hay otra sintaxis un poco más farragosas y
antiguas)
El operador await solo se puede usar en funciones que hayan sido decla-
radas anteponiendo la palabra reservada async. Esto hace que la función sea
asíncrona. También convierte el valor devuelvo por la función en una promesa
Aquí usaramos las promesas en la función fetch() que sirve para que un
programa en JavaScript haga una petición HTTP, típicamente una petición
REST/ROA
197
console.log("Respuesta_json: "+ respuesta_json);
return respuesta_json;
}
1 "use strict"
2 async function trae_resultado (numero) {
3 let dir_base = "http://localhost:3000/"
4
16 span01.textContent = numero;
17 span02.textContent = await trae_resultado(numero);
18 }
19
198
Línea 8. Como fetch() devuelve una promesa, hay que anteponer await
Línea 9. Como json() devuelve una promesa, hay que anteponer await
Línea 2. Como en las líneas 8 y 9 hay un await, hay que anteponer
async. Esto provoca que trae_resultado devuelva una promesa
Línea 17. Como trae_resultado devuelve una promesa, hay que ante-
poner await
Línea 12. Como en la línea 17 hay un await, hay que anteponer async
La función manej_boton01 ya es de nivel global, no es necesario nigún await
más (no se usa al registrar el manejador con addEventListener pero que esto
no lee el valor devuelto por la función, solo lo vincula con el evento)
Dirección base:
http://localhost:3000
Recurso:
/api/dobla/
Parámetro: num
URL Completa:
http://localhost:3000/api/dobla/:num
Ficheros requeridos
Necesitamos los siguientes cheros:
dobla_client.html
dobla_client.js
199
dobla_server.js
Script que congura Express para servir tanto las peticiones REST
como los cheros del cliente
http://localhost:3000/api/dobla/:num
http://localhost:3000/dobla_client.html
http://localhost:3000/js/dobla_client.js
~/www/site01/
2) Copiar
dobla_client.html a ~/www/site01/
dobla_client.js a ~/www/site01/js
3) Lanzar Express.js con el chero de conguración
node dobla_server.js
http://localhost:3000/api/dobla/10
5) (opcional)
http://localhost:3000/js/dobla_client.js
6) Comprobar que Express sirve la página web y que esta funciona correc-
tamente
http://localhost:3000/dobla_client.html
200
dobla_client.html
<!DOCTYPE html>
<html lang="es-ES">
<head>
<meta charset="utf-8">
<title>Cómo enviar peticiones REST</title>
</head>
<body>
<button id="boton01">Enviar un valor </button>
<br>
Valor enviado: <span id="span01"></span>
<br>
Valor recibido: <span id="span02"></span>
<script src="js/dobla_client.js">
</script>
</body>
</html>
http://ortuno.es/dobla_client.html
dobla_client.js
"use strict"
async function trae_resultado (numero) {
let dir_base = "http://localhost:3000/"
span01.textContent = numero;
span02.textContent = await trae_resultado(numero);
}
http://ortuno.es/js/dobla_client.js.html
201
Atención en la construcción del path:
http://localhost:3000/api/dobla//:num
http://localhost:3000api/dobla/:num
dobla_server.js
const express = require('express');
const app = express();
const puerto = process.env.PORT || 3000;
app.use(express.json());
// middleware necesario para procesar las peticiones
// POST que incluyan un cuerpo json
// Direccionamiento estático:
const path = require('path');
// Importamos el módulo path
app.use(express.static(dir_raiz))
// Sirve todos los ficheros del directorio raiz
202
console.log("La respuesta es " + doblado);
doblado_json = JSON.stringify(doblado);
res.json(doblado_json);
})
// Error 404
app.use((req, res) => {
res.type('text/plain');
res.status(404);
res.send('404 - Dirección no encontrada');
})
// Error 500
app.use((err, req, res, next) => {
console.error(err.message);
res.type('text/plain');
res.status(500);
res.send('500 - Error en el servidor');
})
http://ortuno.es/dobla_server.js.html
return respuesta;
}
203