Programación Web (Para Principiantes)
Programación Web (Para Principiantes)
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 . . . . . . . . . . . . . . . . . . . . . . 18
1.7. Formularios . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.8. Elementos obsoletos . . . . . . . . . . . . . . . . . . . . . . . . 32
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 . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
4.7. Operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
4.8. Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
4.9. Tipos de variables . . . . . . . . . . . . . . . . . . . . . . . . . 94
4.10. Sentencias de control . . . . . . . . . . . . . . . . . . . . . . . 98
4.11. Procesamiento de cadenas . . . . . . . . . . . . . . . . . . . . 101
4.12. Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
4.13. Plain Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
2
4.14. Excepciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
4.15. Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
6. JavaScript(ii) 144
6.1. Números aleatorios . . . . . . . . . . . . . . . . . . . . . . . . 144
6.2. Fecha y Hora en JavaScript . . . . . . . . . . . . . . . . . . . 144
6.3. Módulos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
6.4. TypeScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
6.5. POO basada en prototipos . . . . . . . . . . . . . . . . . . . . 153
6.6. POO basada en herencia . . . . . . . . . . . . . . . . . . . . . 156
8. Json 166
8.1. Introducción a JSON . . . . . . . . . . . . . . . . . . . . . . . 166
8.2. Funciones para procesar JSON . . . . . . . . . . . . . . . . . . 170
9. AJAX 171
9.1. Introducción a Ajax . . . . . . . . . . . . . . . . . . . . . . . . 171
9.2. JSONP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
9.3. Ejemplo: cambio de divisas . . . . . . . . . . . . . . . . . . . . 174
3
11.Express 180
11.1. Introducción a Express . . . . . . . . . . . . . . . . . . . . . . 180
11.2. Instalación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
11.3. Diseño de las URL . . . . . . . . . . . . . . . . . . . . . . . . 181
11.4. API REST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
11.5. Conguración de Express . . . . . . . . . . . . . . . . . . . . . 182
11.6. Status Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
11.7. Ejemplo completo . . . . . . . . . . . . . . . . . . . . . . . . . 187
11.8. Ficheros estáticos . . . . . . . . . . . . . . . . . . . . . . . . . 188
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
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
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>
12
Algunas etiquetas de estos elementos se pueden omitir en ciertas cir-
cunstancias y el documento sigue siendo válido, quedan sobreentendidas
(head, body, html). Pero siempre es preferible ponerlo todo
Cuidado:
DOCTYPE
La declaración <!DOCTYPE html> es obligatoria al comienzo de un docu-
mento HTML 5
13
En HTML 4.x y anteriores, esto era más complicado
Ejemplos:
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>
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
14
En otros elementos son incorrectas. Aunque el navegador suele ignorar-
los y mostrar la página igualmente
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>
Signo igual
15
1.5. Cabecera del documento
Elemento head
El elemento head es la cabecera del documento.
Es un contenedor para metadatos del documento HTML. Esta informa-
ción nunca se muestra directamente. Sus elementos son
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>
16
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>
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
17
Ambas informaciones pueden ser discrepantes. El convenio es dar prece-
dencia a HTTP. Problema: un servidor que tenga mezcladas páginas HTML
4 (normalmente en ISO-8859-1) y HTML 5 (normalmente UTF-8)
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
18
Entre un párrafo y otro hay
Un salto de línea
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 -->
19
br
La etiqueta <br> dene el elemento breaking line
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
h1-h6
Las etiquetas <h1>, <h2>, ... <h6>, denen elementos heading (encabeza-
do)
20
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
<a href="mailto:[email protected]?Subject=Contacto%20web">
Envíame un correo</a>
O enlazar un script
21
Los enlaces pueden ser
<a href="http://linkedsite/url.html">Documento</a>
Relativos
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>
22
Anchor al estilo HTML 4
En HTML 4, un anchor se creaba deniendo un elemento <a>
Ejemplo
[.....]
[.....]
Atributo target
Añadiendo a un enlance el atributo target="_blank", este se abrirá en
una nueva pestaña del navegador
23
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
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>
24
<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>
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>
25
<dd>
Juan García
</dd>
<dt>
Centro de origen
</dt>
<dd>
ESTIT-URJC
</dd>
</dl>
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>
26
Observa que normalmente indicaremos el path (trayecto) del chero con
la imagen de manera relativa. El trayecto no empieza por el carácter barra
(/)
urjc.png
El directorio padre del directorio donde está este html, hay un directorio
llamado practica03, y dentro, un chero llamado urjc.png
/urjc.png
27
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/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
<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
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>
29
input: tipos de HTML5
HTML 5 añade nuevos tipos de input
month
number
range
search
tel
time
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">
30
<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>
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:
31
Haciendo clic sobre esta etiqueta, se activa el elemento
<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
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
€ €
Ñ Ñ
ñ ñ
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 €
Sin la ayuda del editor, sería difícil anidar las etiquetas correctamente
Etc
34
apm install atom-beautify
Uso:
2. Ctrl alt b
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>
37
2. Hoja de estilos interna
https://www.w3schools.com/css/css_howto.asp
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
39
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:
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
40
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
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.
41
p span { color: red; }
[...]
<p>
...
<span>Texto1</span>
<a href="">...<span>Texto2</span></a>
...
</p>
Texto 1 evidentemente cumple la regla.
Texto 2 es un elemento span contenido dentro de un enlace contenido
dentro de un elemento p. Por tanto, Texto 2 están contenido dentro de un p.
Aunque no sea descendiente directo, es descendiente y la regla se aplica.
Ejercicio
¾Qué elementos se seleccionarían con estos tipos de selectores?
p a { color: red; }
p * a { color: red; }
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
42
Esta regla se aplica a cualquier elemento de clase destacado
<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
Esta regla se aplica a los elementos de tipo párrafo, que además sean de
clase destacado. (En este ejemplo, solo una vez)
43
.a.b {...}
Esta regla se aplica a los elementos de clase a que además sean de clase b
Es equivalente a decir los elementos de clase b que además sean de clase
a (las clases son atributos, y los atributos no tienen orden)
http://ortuno.es/concatenacion_clases.html
Ejercicio
¾Qué elementos se seleccionarían con estos tipos de selectores?
p.aviso { ... }
p .aviso { ... }
p, .aviso { ... }
*.aviso { ... }
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
Ejercicio: Combinación de selectores
¾Qué elementos se seleccionarían con estos tipos de selectores?
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
45
Especicación del color
Hay dos formas principales de indicar el color
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:
46
Los principales atributos relacionados con el color son
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
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
47
2.5. Atributos relacionados con el texto
Atributos relacionados con el texto
Alineación
Subrayado
Tamaño
Estilo
border-width
border-style
border-color
https://www.w3schools.com/css/css_border.asp
48
Tipos de elementos (I)
El estándar HTML clasica a todos sus elementos en dos grandes grupos:
Elementos de línea:
Cada vez que se inserta una etiqueta HTML, se crea una nueva caja
rectangular que encierra los contenidos de ese elemento
su borde
49
50
El modelo de cajas (III)
Los navegadores crean y colocan las cajas de forma automática, pero
CSS permite modicar todas sus características. Cada una de las cajas
está formada por seis partes, tal y como muestra la siguiente imagen:
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
51
Si indicamos 4 valores, se reeren a arriba, derecha, abajo, izquierda
margin: 8px
Visualización
CSS dene otros cuatro atributos para controlar su visualización: dis-
play, visibility, overow y z-index.
52
53
Diferencias entre display y visibility
Otros atributos
CSS tiene muchos otros atributos que no veremos aquí
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
holamundo.js
El directorio padre del directorio donde está este html, hay un directorio
llamado practica03, y dentro, un chero llamado holamundo.js
74
Si anteponemos la barra, el signicado cambia por completo
/holamundo.js
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
75
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
¾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
76
Entorno Linux
Instalación
Ejecución
nodejs holamundo.js
O bien
node holamundo.js
jperez@alpha:~$ ./holamundo.js
#!/usr/bin/nodejs
O bien
#!/usr/bin/env nodejs
Entorno macOS
node holamundo.js
#!/usr/bin/env nodejs
77
4.4. Sintaxis
Comentarios
Los comentarios se pueden indicar de dos formas
Sentencias y expresiones
En JavaScript hay
78
Si el programador no incluye los puntos y coma, el parser los añade
con la automatic semicolon insertion. De hecho el JavaScript moderno
tiende a omitir los puntos y coma, lo que en ciertos casos puede producir
errores y confusiones.
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'
...
}
79
4.5. Tipos de datos
Tipos de datos
En JavaScript hay dos tipos de valores
primitive values :
boolean, number, string, null, undened
Objetos
Booleanos
true
false
Números
Strings (cadenas)
'lorem' "ipsum"
80
En JavaScript hay dos tipos de datos para indicar que falta información
undened
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 {})
'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
81
Si declaramos las variables con let y no con var, el comportamiento es
algo mejor, saltará una excepción si intentamos usar una variable antes
de denirla o si intentamos declarar la misma variable más de una vez
if (x===undefined || x===null){
}
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.
82
'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
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
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
¾Sensible a mayúsculas?
83
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:
84
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;
console.log(x); // 2
x-=2;
console.log(x); // 0
85
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
Operadores lógicos
&& || !
86
> !(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;
}
87
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;
(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
88
(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
89
'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
f("holahola", function(x) {
90
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;
console.log(a); // 3
f(a);
console.log(a); // 3
91
Paso por referencia
En JavaScript no existe el paso por referencia. Si realmente lo necesita-
mos, podemos simularlo envolviendo el valor en un array
'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
'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
92
Podemos conocer el número de argumentos recibidos usando la propiedad
length del objeto predenido arguments
'use strict'
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
93
Si pasamos un valor, se devuelve ese valor (el or lo considera cierto)
aunque para javascript no sea ni true ni false
'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
94
Globales
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
}
function g(){
var x=3; // Variable local de g
}
f();
95
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'
'use strict'
function f() {
var x = 1;
if (true) {
var x = 2; // La misma variable. Destruimos valor previo
console.log(x); // 2
96
}
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
6 Este ejemplo usa un plain object, que veremos al nal de este tema
97
'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.
'use strict'
let y;
let x=":";
switch(x){
case(';'):
y="punto y coma";
break;
98
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:
so='no soportado';
}
console.log(so);
99
La expresión de cada case puede ser cualquiera:
'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); //*****
for
La sentencia for también es como en C y muchos otros lenguajes
100
Entre paréntesis y separado por punto y coma se indica la sentencia ini-
cial, la condición de permanencia y la sentencia que se ejecuta después
de cada ejecución del cuerpo
'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";
101
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'
102
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)
''
103
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;
104
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); // []
105
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']
106
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
107
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
108
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
109
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
110
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
111
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!
112
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
113
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
114
En cualquier navegador web, a menos que sea muy antiguo
115
Funcionalidad que realmente mejora la experiencia de usuario:
Validación de formularios
Formularios mejorados
Ejemplos
HTML SVG
https://github.com/d3/d3/wiki/Gallery
...
116
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
117
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
118
¾Dónde pasa?
¾Cómo responder?
event object. Objeto con detalles sobre el evento: coordenadas del ratón,
tecla pulsada, etc
El manejador
119
<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
120
Un evento que llega a un objeto element, se propaga a todos los antece-
sores de ese elemento. Ejemplo:
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
121
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
122
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
123
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>
124
<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
document.createElement()
125
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
126
<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
127
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()
128
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
11
Quitar y poner la clase
<style>
.oculto {
display: none;
}
</style>
11 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
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
Todos los que tengan cierto atributo, con cierto valor, p.e. el chero de
una imagen
...
136
Pero en general lo recomendable será seleccionar un elemento por una
clase
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
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).
Así que hay que convertir a notaciónDromedario
137
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
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
138
Un segundo div de clase enter que contiene un texto que contiene un
span
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
139
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
<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");
}
http://ortuno.es/eventos_03.html
5.10. Formularios
Formularios (1)
Para acceder al valor de un formulario
http://ortuno.es/formulario_01.html
Formularios (2)
Para consultar el estado de un radiobutton o un checkbox, usamos un
selector como
input[name=figura]:checked
141
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 manej01(event) {
let display = document.querySelector("#validacion");
let contrasenia = document.querySelector("#contrasenia").value;
if (contrasenia.length >= contrasenia_minima) {
display.textContent = "Contraseña aceptable";
} else {
display.textContent = "Contraseña muy corta";
}
};
let campo_contra = document.querySelector("#contrasenia");
campo_contra.addEventListener("change", manej01);
http://ortuno.es/validacion_01.html
142
Podemos mejorar el ejemplo anterior, de forma que no sea necesario que
el usuario acabe de editar un campo para obtener realimentación. Para ello
capturamos los eventos
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;
valida_contrasenia(contrasenia);
};
let campo_contra = document.querySelector("#contrasenia");
campo_contra.addEventListener("change", manej01);
campo_contra.addEventListener("keyup", manej01);
campo_contra.addEventListener("paste", manej01);
campo_contra.addEventListener("mouseup", manej01);
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'
6.3. Módulos
Módulos
Un módulo es
CommonJS
Para Node.js
RequireJS
Para el navegador
148
Extensiones de los cheros
El mismo código ECMASCript 6 con módulos podemos ejecutarlo tanto
en node.js como en el navegador. Con una diferencia:
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
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());
149
Los módulos también se pueden usar de esta forma
'use strict'
import { f, g } from './modulo';
console.log(f());
console.log(g());
Observaciones
.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
150
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
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
151
En este caso, tendrás que importar módulos especicando la extensión
.js, con lo que el código ya no funcionará en node.js
Ejemplo:
6.4. TypeScript
TypeScript
Como hemos visto, JavaScript tiene
Muchos inconvenientes.
Forman parte de la esencia del lenguaje, para evitarlos habría que usar
un lenguaje diferente
152
6.5. POO basada en prototipos
POO basada en herencia vs POO basada en prototipos
La gran mayoría de lenguajes y herramientas diversas que emplean POO
(programación orientada a objetos) aplican POO basada en herencia
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
153
Arquitectura frágil
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
154
Problemas de la POO basada en prototipos (2)
La exibilidad del paradigma añade complejidad al intérprete/compilador,
lo que afecta al rendimiento
Eric Elliott
http://tinyurl.com/zbtjruf
http://proquest.safaribooksonline.com/book/programming/javascript/9781491950289
http://proquest.safaribooksonline.com/book/programming/javascript/9781457185304
155
6.6. POO basada en herencia
POO basada en herencia en JavaScript
El lenguaje JavaScript usa POO basada en prototipos.
Tras una cierta polémica, ECMASCript 6 soporta POO basada en heren-
cia
Los argumentos principales por los que se acepta este paso atrás son
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
156
'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
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
157
'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;
}
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
http://exploringjs.com/es6/ch_classes.html#sec_overview-classes
158
7. APIs de HTML5
Web Storage
Web Workers
Geolocation
Canvas
Web Messaging
https://en.wikipedia.org/wiki/HTML5#New_APIs
159
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:
160
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
161
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
162
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
163
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;
164
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
165
8. Json
Value
Fuente:json.org
166
Number
Fuente:json.org
String
Fuente:json.org
167
Array
Fuente:json.org
Objetos
Fuente:json.org
Ejemplos correctos
"hola, mundo"
4243.12
-947e-5
null
[1,2,3,4]
168
[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
]
}
169
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' ] }
170
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
171
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
172
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:
173
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
174
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
);
175
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
176
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">
177
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
178
let mi_marcador = L.marker(coord_labIII).addTo(mi_mapa);
mi_marcador.bindPopup("Laboratorios III").openPopup();
http://ortuno.es/openstreet2.html
179
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
180
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
181
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
182
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 )
183
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())
12
. 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);
});
184
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
185
// 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
186
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
187
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
188
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
189
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
190
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
191
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
192
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
193
Figura 1: Same-Origin Policy
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)
194
En los ejemplos vistos en la asignatura hasta ahora, el navegador leía los
cheros HTML y los cheros JavaScript directamente del sistema de cheros
local (el disco duro). Pero si siguiéramos trabajando así, incumpliríamos la
same-origin policy (y no funcionaría a menos que conguráramos CORS)
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
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
195
Ese resultado es un objeto Response que contiene la respuesta HTTP en
bruto, normalmente al programador lo que le interesará es el contenido
en json. Para ello, el objeto Response dispone el método json() que
devuelve una segunda promesa, con el objeto json.
return respuesta_json;
}
196
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
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
Dirección base:
http://localhost:3000
197
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
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
198
4) Comprobar que el servidor atiende a las peticiones REST, pidiendo con
tu navegador una página como p.e.
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
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/"
199
console.log("Respuesta_json: "+ respuesta_json);
return respuesta_json;
}
span01.textContent = numero;
span02.textContent = await trae_resultado(numero);
}
http://ortuno.es/js/dobla_client.js.html
http://localhost:3000/api/dobla//:num
http://localhost:3000api/dobla/:num
dobla_server.js
200
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
// 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
201
Si el código no es 200, signica que ha habido problemas y por tanto
no podemos extraer ningún objeto json
return respuesta;
}
202