Juan lleva tiempo desarrollando páginas web con los lenguajes HTML y CSS. Durante todo este tiempo ha ido mejorando y avanzando en el diseño de sitios cada vez más complejos.
Pero en muchos momentos echa de menos poder hacer webs más dinámicas e interactivas. Se acerca a preguntar a Ana, la experta en tecnologías de la empresa, y le pregunta cómo conseguir darle esa interactividad que busca a sus páginas web.
Ana le dice que debe aprender algún lenguaje de script de cliente. Le comenta que con HTML consigues estructurar los contenidos, con CSS le das un aspecto elegante y con cierta retroalimentación. Pero si lo que deseas es cambiar elementos, contenidos y estilos de forma dinámica, necesitas utilizar un lenguaje de script de cliente.
En esta unidad vamos a aprender a manipular los documentos Web de forma dinámica a través del lenguaje de script de cliente JavaScript.
Repasaremos la evolución de este lenguaje y veremos la sintaxis básica necesaria para poder trabajar los documentos Web.
La manipulación de los documentos Web requiere conocer las estructuras de información con las que trabaja el navegador cuando carga y mientras visualiza un documento. También necesitaremos aprender las propiedades y los métodos que nos proporciona el lenguaje JavaScript para acceder, crear, modificar y/o eliminar los distintos elementos y atributos de nuestro documento Web.
Juan lo tiene decidido, quiere mejorar el desarrollo de sus páginas web y se va a poner manos a la obra. Pero ¿qué es un lenguaje de script?, ¿qué tiene que ver el cliente?, ¿qué lenguaje escoger?
Le surgen muchas dudas, pero nada que no puede resolverse investigando y recabando información.
Ana le ve indeciso y decide hablar con él. Juan le plantea sus dudas y ella le resuelve algunas. Son lenguajes de script porque suelen ser lenguajes interpretados en lugar de compilados. También le comenta que si lo que quiere es dar dinamismo a sus paginas webs solo tiene que programar la parte de cliente. Y con cliente se refiere al navegador. El navegador es el cliente que utilizamos habitualmente para conectarnos con los servidores de Internet.
Los lenguajes de script de cliente, también son conocidos como lenguajes client-side o front-end, son aquellos que se utilizan en los navegadores para manejar las aplicaciones web. En la actualidad también se encargan de actualizar la interfaz de manera asíncrona con tecnologías como AJAX.
Aunque con anterioridad existían varios lenguajes de script de cliente como: JScript, ActionScript, Javascript, VBScript o PerlScript, la mayoría desaparecieron, dejaron de usarse o se unieron a Javascript cuando se creó la estandarización de ECMAScript.
En la actualidad también existen otros lenguajes como CoffeeScript, TypeScript, PureScript, Dart, Elm, que son metalenguajes de Javascript o que, para su funcionamiento final en los servidores web, se transpilan a Javascript.
Todo ello nos lleva a decir que Javascript es el lenguaje de script de cliente más usado en la actualidad, además es el único que pueden ejecutar los navegadores sin tener que instalar elementos adicionales.
Juan entiende que necesita un lenguaje de programación que pueda ejecutarse en los navegadores. Pero ¿cuál?
Él sabe que los navegadores actuales son capaces de interpretar los lenguajes HTML y CSS. Eso ya lo conoce.
Sigue investigando un poco y viendo las características de los navegadores actuales y lo ve muy claro. El lenguaje script que pueden ejecutar los navegadores es Javascript. Este lenguaje ya lleva con nosotros unas décadas y se ha hecho con un puesto de honor en nuestros navegadores.
Juan conversa con Ana y le cuenta que quiere empezar a programar la parte dinámica de sus páginas web con Javascript. Ana le habla de que cuando surgieron estos lenguajes script de cliente cada compañía quería imponer el suyo, pero que esto creaba incompatibilidades y que cada empresa tuviese que ir desarrollando en paralelo un navegador y un lenguaje script de cliente. Todo eso acabo con la estandarización de Javascript en ECMAScript.
El lenguaje Javascript fue creado por Brendan Eich en 1995 para el navegador NetScape.
En 1997 para estandarizar Javascript se creó el ECMAScript. Desde entonces el nombre técnico de Javascript es ECMAScript.
En 1998 se crea el elemento XMLHttpRequest por parte de Microsoft. Gracias a este elemento, las páginas web se vuelve mucho más dinámicas, ya que nos permite cargar contenido e interactuar con el servidor sin tener que volver a cargar la página web.
En 2000 Douglas Crockford estable las bases para los documentos JSON una forma de transmitir objetos en Javascript.
En 2006 John Resig crea la librería JQuery que facilita enormemente el trabajo con Javascript. Posteriormente, muchas de las utilidades que se utilizaban en JQuery se implementaron en el estándar de Javascript.
En 2009 Ryan Dahl, basándose en el novedoso motor Javascript V8 de Google Chrome, creo NodeJS. Un sistema que interpreta Javascript sin necesidad de un navegador. Esto permitió utilizar Javascript no solo en el frontend como se estaba utilizando hasta entonces, también se empezó a utilizar en la parte servidor, para el acceso a bases de datos, en aplicaciones de escritorio e incluso en aplicaciones IoT.
Javascript es un lenguaje que va actualizándose año a año y el uso de una versión u otra depende de los navegadores que se utilicen para visualizar nuestros scripts. Las versiones donde se produjeron los mayores cambios fueron en las versiones ECMAScript 5 y ECMAScript 6. La versión que actualmente se considera como la mínima para desarrollar código nuevo es la ECMAScript 6.
Se agregaron expresiones regulares. Se agregó try/catch. Se agregó switch. Se agregó do- while.
ES4
ECMAScript 4
Nunca liberado
ES5
ECMAScript 5 (2009)
Se agregó "strict mode" Se agregó soporte JSON Se agregó String.trim() Se agregó Array.isArray() Se agregaron métodos de iteración de Array Se agregaron las comas finales para los objetos literales
ES6
ECMAScript 2015
Se agregaron let y const Se agregaron valores de parámetros por defecto Se agregó Array.find() Se agregó Array.findIndex()
Se agregó relleno de cadenas de caracteres. Se agregó Object.entries() Se agregó Object.values() Se agregaron funciones asíncronas: async Se agregó memoria compartida. Se agrego las comillas finales a los parámetros de funciones
ECMAScript 2018
Se agregó el operador de difusion: ... Se agregó la iteración asyncrona Se agregó Promise.finally() Mejoras en las expresiones regulares
ECMAScript 2019
String.trimStart() String.trimEnd() Array.flat() Object.fromEntries Vinculación opcinal de catch
Interpretado: El código que se escribe no se compila para obtener un ejecutable, sino que necesita de un intérprete que vaya ejecutando línea a línea. Por eso a los programas escritos por un lenguaje interpretado se le suelen llamar script. Esto puede hacer que sea un lenguaje más lento, pero permite que trasladar el código de una plataforma a otra sea más sencillo. En entornos de producción, sí que se puede optimizar el código con compilaciones JIT (Just In Time).
Estructurado: Es estructurado porque utiliza estructuras de control: como bloques secuenciales, bloques condicionales y bloques iterativos.
Orientado a objetos basados en prototipos o classless, es decir, no es orientado a objetos 'puro' como Java, C++, Python, etc. Aunque a partir de ECMAScript 6 se han añadido soporte de clases y podemos escribir código con una sintaxis parecida al resto de lenguajes de programación orientados a objetos 'puros'. Hay que tener en cuenta que Javascript sigue trabajando con una programación orientada a objetos basada en prototipos y este añadido es solo sintáctico.
De tipado débil y dinámico: Las variables no hay que declararla con un tipo definido fijo, sino que el tipo de dato lo estable el contenido de dicha variable. Además, a lo largo de la ejecución de un script una variable puede contener datos de los distintos tipos de datos que hay.
Multiplataforma: Puede ejecutarse en distintos navegadores y distintos sistemas operativos
Alexander Zvir. Árbol solitario(Licencia uso gratuito de Pixabay)El elemento HTML script se utiliza para insertar código ejecutable. El código Javascript se puede escribir directamente entre las etiquetas de apertura y cierre o en un archivo externo. El archivo externo debe indicarse mediante el atributo HTML src.
Durante el proceso de carga de una página web, si el navegador se encuentra con un script, debe parar la carga de la página HTML y comenzar a descargar este script. En la actualidad los scripts pueden ser cientos de veces más grandes que las propias páginas web, por lo que el proceso de cargar una página se ralentizaría y tendríamos un efecto indeseado. Además, podría darse el caso de que el script trate de acceder a elementos del DOM que aún no se han cargado.
Para solucionar este problema podemos utilizar los atributos defer y async en el elemento HTML script, siempre que se trate de un archivo externo proporcionado por el atributo src.
El atributo defer difiere la carga del script hasta que se ha completado los elementos del DOM . El atributo async indica que el script es independiente y no bloqueará la carga del DOM ni de otros scripts.
En el siguiente enlace puedes ampliar información sobre el elemento HTML <a href="https://www.w3schools.com/tags/tag_script.asp" target="_blank" class="html" title="Haz click aquí para ir a la página de W3Schools." rel="noopener"><em lang="en">script</em></a>.
En navegadores antiguos las etiquetas HTML script se debían poner en el elemento HTML head cuando no necesitaban acceder al documento HTML o al final del elemento HTML body cuando se necesitaba acceder a alguna parte del documento. Además, en el elemento HTML script había que indicar con el atributo type que era un documento Javascript usando el valor MIME text/javascript. En ocasiones también se debían utilizar otros atributos HTML ya obsoletos como charset y language.
Además, si el documento era XHTML el código Javascript que se añadía entre las etiquetas de apertura y cierre del elemento HTML script debía de estar dentro de un bloque XML CDATA. Esto era debido a que en XHTML no se podían utilizar los ángulos < >.
En HTML 5 ya no son necesarios estos atributos ni el bloque CDATA.
En el siguiente enlace puedes ampliar información sobre el elemento HTML <a href="https://www.w3schools.com/tags/tag_noscript.asp" target="_blank" title="Haz click aquí para ir a la página de W3Schools" rel="noopener" class="html">noscript</a>.
Alexander Zvir. Tren en blanco y negro.(Licencia uso gratuito de Pixabay)Como cualquier lenguaje estructurado, cuando escribimos un script, las instrucciones las indicamos mediantes sentencias. Una sentencia es como una oración de un idioma. Una sentencia debe tener sentido semántico, es decir, indicar una instrucción completa y no quedarse a medias. Una sentencia puede ser compleja y tener como parte de la sentencia subbloques de sentencias.
Las sentencias las podemos agrupar en tres tipos de bloques:
Bloque secuencial: Las instrucciones va en orden secuencial, según están escritas y se van ejecutando de arriba a abajo.
Bloque condicional: Existe un conjunto de sentencias que solo se ejecutan si se cumple una determinada condición. Da lugar a distintos caminos en la ejecución de un script.
Bloque repetitivo: Existe un conjunto de sentencias que se repiten o no dependiendo de una condición. Se les suele llamar bucle. Es importante que la condición de salida del bucle se pueda dar en algún momento para evitar que el script quede bloqueado.
Para la construcción de estas sentencias utilizamos una serie de elementos del lenguaje Javascript: palabras reservadas, variables y operadores. También podemos y debemos utilizar comentarios para documentar el código.
Elaboración propia. Herramienta de desarrollo del navegador Firefox
Casi todos los navegadores actuales tienen una herramienta de desarrollo que nos ayudará a trabajar con Javascript.
Tanto Firefox, como Chrome y Edge utilizan la tecla F12 para acceder a dicha herramienta.
Dentro de esta herramienta de desarrollo podemos interactuar con la página web de forma dinámica en la pestaña Consola. Para trabajar con Javascript haremos uso de esta pestaña. También podremos ver el código fuente de una web en la pestaña Fuentes. Otra pestaña básica es la pestaña Elementos que sirve para comprobar los elementos HTML y sus estilos CSS.
Comentarios en línea: Se utilizan para hacer un comentario corto sobre una instrucción o al final de esta. Se indican mediante las dos barras //. Todo el texto desde las dos barras hasta el salto de línea se comentará.
Comentarios de bloque: Se utilizan para crear un comentario más amplio de varias líneas. Se utiliza la barra y el asterisco para marcar el inicio /* y el asterisco y la barra */ para marcar el final del comentario.
Además de documentar los scripts, los comentarios se utilizan a la hora de depurar el código. Cuando tenemos algún problema con nuestro código y queremos ir probándolo trozo a trozo, podemos ir comentando bloques de código que no queramos utilizar de modo que sigan ahí, pero que no se ejecuten y no los tengamos que borrar.
En el lenguaje Javascript existen una serie de palabras reservadas que el lenguaje interpreta como acciones que debe realizar. Iremos conociendo muchas de estas palabras reservadas: qué funcionalidad tienen y cómo utilizarlas. Estas palabras reservada no pueden utilizarse como identificadores de nuestras construcciones lógicas, es decir, nuestras variables y funciones.
Las palabras reservadas de Javascript son:
<span>await break case catch class const continue debugger default delete do else export extends finally for function if import in instanceof new return super switch this throw try typeof var void while with yield</span>
Otras palabras reservada en el modo estricto son:
<span>implements interface let package private protected public static yield</span>
Además, hay una serie de literales, números especiales y tipos de datos únicos que no recomendados usar como identificadores, que son:
Alexander Zvir. Escalera en blanco y negro.(Licencia uso gratuito de Pixabay)Las variables son espacios reservados para almacenar datos. Cuando declaramos una variable le establecemos un identificador. Cuando queramos trabajar con los datos almacenados en dicha variable, utilizaremos los identificadores que les hemos asignado. Existen dos forma de declarar una variable:
Con let, si la variable es dinámica y puede cambiar de valor a lo largo de la ejecución del script. Es el valor por defecto.
Con const, si la variable una vez reciba un valor este no va a cambiar. Es decir, su valor va a ser constante.
En las versiones anteriores de Javascript también se podía declarar las variables con var. No es recomendable seguir utilizando var. En su lugar debemos usar let.
El problema de usar var es que las variables se declaran como globales o globales a nivel de función. Además permite redeclarar variables, por lo que si no eres consciente de ello puedes perder los datos almacenados al sobre escribir valores. También permite utilizar la variable antes de que esta sea declarada lo que hace que el código no esté ordenado.
Al declarar una variable podemos inicializarlas a un valor o no. Si no las inicializamos a un valor, el valor por defecto que contendrán será undefined.
Se dice que Javascript es un lenguaje débilmente tipado, ya que las variables no tienen asociado un tipo de dato, es decir, solo son identificadores que se asocian a espacios donde almacenar datos. Esto se debe a que en Javascript el tipo de dato está asociado al valor de la variable y no a la variable. Además, se dice que Javascript es un lenguaje de tipado dinámico, ya que una variable durante la ejecución del script podría contener un valor de un tipo y posterior contener un valor de otro tipo distinto.
En el siguiente enlace de la web de MDN puedes ampliar información sobre el uso de <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/let" target="_blank" title="Haz click aquí para ir a la página de MDN." class="html" rel="noopener">let</a>, <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/const" target="_blank" title="Haz click aquí para ir a la página de MDN." class="html" rel="noopener">const</a> y <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/var" target="_blank" title="Haz click aquí para ir a la página de MDN." class="html" rel="noopener">var</a>.
Los identificadores son valores para nombrar las entidades que declaramos en el lenguaje Javascript, normalmente variables y funciones.
let numero // correcto
let miNumero // correcto
let _unValor_ // correcto
let $NOMBRE // correcto
let $$texto // correcto
let pequeño // correcto, pero no recomendado usa ñ
let número // correcto, pero no recomendado usa tilde
let dirección // correcto, pero no recomendado usa tilde
A la hora de crear un identificador para nombrar una variable o una función debemos tener en cuenta la siguiente regla:
El primer carácter debe ser una letra, un guion bajo o un símbolo de dólar, los siguientes caracteres pueden ser cualquier carácter unicode, incluyendo números. Se recomienda usar solo letras anglosajonas, es decir, no usar tildes ni la letra ñ.
Elaboración propia. Consola de depuración del navegador Firefox(CC BY-NC-SA)
El objeto window contiene una propiedad console, que es un objeto Console, que sirve para tener acceso a la consola de depuración del navegador.
Gracias al comando console.log() podemos mostrar textos o el contenido de las variables en dicha consola de depuración.
Esta funcionalidad nos va a ser muy útil para ir comprobando en determinados lugares de nuestros scripts si todo va funcionando correctamente.
En la imagen se puede apreciar que además de mostrar los resultados de la instrucción console.log() se puede interactuar con la consola y ejecutar código como el mostrado: document.querySelector("#miNombre")
En el siguiente enlace puedes ampliar información sobre el objeto console.
Los tipos de datos son una categorización de los valores que contienen las variables que nos sirven para saber qué operaciones podemos realizar con ellos. Por ejemplo: si tenemos dos números podemos sumarlos, pero si tenemos dos cadenas de texto no podremos sumarlos. En ese caso, lo que queremos será concatenarlos y crear una única cadena de texto.
Los tipos de datos más importantes en Javascript son:
Boolean: Se utiliza para almacenar valores lógicos. Solo puede tomar dos valores: true o false.
let esCorrecto = false;
let condicion = 5>3;
console.log("Es correcto: ",esCorrecto); // false
alert(condicion); // true
Number: Se utiliza para almacenar números en general. Existen unos números especiales:
Infinity: El concepto matemático de Infinito, es mayor que cualquier otro número. También tenemos su opuesto -Infinity.
NaN: Not a Number (no es un número). Es devuelto cuando una expresión matemática no es correcta. Cuando este número se opera con otros, su resultado sigue siendo NaN, por lo que el resultado final de la operación será NaN.
let valor1 = 1 / 0;
let valor2 = "nombre" / 4;
let valor3 = (2 * 3 + 5)/3**2
console.log(valor1);
console.log(valor2);
console.log(valor3);
String: Se utiliza para almacenar cadenas de texto de cualquier tamaño. Para asignarle un valor literal este debe ir entre comillas dobles ("), simples (') o invertidas (`). Si la cadena literal tiene comillas invertidas puede interpolar expresiones y variables con el formato ${variable}.
let nombre = "Paco";
alert(`Hola ${name}!`); // Hola, Paco!
null: es un tipo de dato con un único valor. Representa una ausencia de objeto.
undefined: al igual que null, es un tipo de dato con un único valor. Representa un valor indefinido o ausente. Aparece cuando una variable es declarada pero no está inicializada a ningún valor.
let valor;
alert(valor); // undefined
Object: es un tipo de dato no primitivo ya que puede almacenar más de un valor. Es una estructura de datos abstracta que nos permite tener una colección de propiedades (pares de clave-valor). A estos objetos literales o literales inicializadores de objeto en otros lenguajes también se les llaman diccionarios.
BigInt: Es un tipo de dato introducido en versiones recientes de Javascript (ECMAScript 2020) que permite almacenar números enteros mayores de 253 -1
En el siguiente enlace de la web de MDN puedes ampliar información sobre el tipo de dato <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt" target="_blank" title="Haz click aquí para ir a la página de MDN." class="html" rel="noopener">BigInt</a> de Javascript.
<strong>typeof</strong> es un operador muy útil cuando estamos trabajando con tipos de datos. Este operador nos devuelve el tipo de dato de una expresión.
En el siguiente enlace de la web de MDN puedes ampliar información sobre el operador<a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/typeof" target="_blank" title="Haz click aquí para ir a la página de MDN." class="html" rel="noopener">typeof</a> de Javascript.
El lenguaje Javascript tiene una serie de operadores con los que podemos desarrollar nuestros scripts. Estos operadores pueden ser unario, binarios o ternarios, dependiendo del número de operandos que necesite. Un operador unario se aplica a un único operando, un operador binario opera con dos operandos y un operador ternario podrá operar con hasta tres operandos. Además, estos operadores los podemos agrupar según la naturaleza de su operación de la siguiente forma:
La asignación básica se escribe con un igual = y se utilizan para asignar el valor de una expresión a una variable. La expresión debe ir en la parte derecha y la variable en la parte izquierda. El resto de operadores de asignación son abreviaciones de una operación matemática y la asignación básica.
Operadores de asignación
Sintaxis
Nombre
Ejemplo
Significado
=
Asignar.
x = y
x = y
+=
Sumar y asignar.
x += y
x = x + y
-=
Restar y asignar.
x -= y
x = x - y
*=
Multiplicar y asignar.
x *= y
x = x * y
/=
Dividir y asignar.
x /= y
x = x / y
%=
Resto y asignar.
x %= y
x = x % y
**=
Potenciar y asignar.
**=
x = x ** y
++
Incrementar. Sumar uno y asignar.
++
x = x + 1
--
Decrementar. Restar uno y asignar.
--
x = x - 1
Por ejemplo, en lugar de escribir: miNumero = miNumero + valor podemos abreviarlo con: miNumero += valor. También podemos abreviar: miNumero = miNumero + 1 con miNumero++.
Se aplican a los tipos de datos numéricos y su resultado suele ser un número. Hay que tener en cuenta que existen unos números especiales: Infinity, -Infinity y NaN. Gracias a estos números, las operaciones en el lenguaje Javascript no generarán excepciones como en otros lenguajes de programación. A lo sumo una operación dará como resultado Not a Number NaN.
El resultado de estos operadores son los esperados matemáticamente:
Operadores matemáticos
Sintaxis
Nombre
Ejemplo
+
Sumar.
x + y
-
Restar.
x - y
*
Multiplicar.
x * y
/
Dividir.
x / y
%
Resto.
x % y
**
Potencia.
x<sup>y</sup>
++
Incrementar.
x + 1
--
Decrementar.
x - 1
+valor
Positivo.
+x
-valor
Negativo.
-x
Recordad que además de estos operadores matemáticos, existen otros operadores que son abreviaciones de una operación matemática y el operador de asignación.
Los operadores de comparación sirven para comparar y ordenar valores. Se pueden aplicar tanto a las variables numéricas como a las cadenas de caracteres. El resultado de estas operaciones será un valor booleano: true o false.
Los operadores lógicos o booleanos sirven para realizar las operaciones lógicas básicas. Gracias a estos operadores podemos realizar condiciones más complejas. El resultado de estas operaciones será un valor booleano: true o false.
A partir deECMAScript2020, también existe un operador de comprobación nula, Nullish coalescing. Este operador devuelve el primer valor si este no es null o undefined. Si el primer valor es de los tipos anteriores, devuelve el segundo valor.
Este operador no devuelve un valor lógico, sino uno de los dos valores indicados.
En el siguiente enlace de la web de MDN puedes ampliar información sobre el operador de comprobación nula.
Operador corchetes [ ] : Sirve para acceder a una propiedad por su nombre. Esta notación es más versátil que la notación punto. Si el identificador de una propiedad está formado por más de una palabra, es el único método para acceder a esa propiedad. El operador punto no funciona con identificadores de más de una palabra. El operador [ ] también puede ser usado con variables que contengan el identificador de la propiedad que queramos crear o a la que queramos acceder, lo que hace que se le pueda asignar de forma dinámica.
Operador punto . : Sirve para acceder a una propiedad o un método del objeto de forma abreviada. Solo se puede utilizar si el identificador es una sola palabra.
Operador punto interrogación ?. :ECMAScript2020 introduce este nuevo operador. Sirve para evitar errores al intentar acceder a propiedades o métodos que no existan en un objeto. Este operador devuelve undefined si no se encuentra la propiedad o el método indicado. Este operador se puede usar para leer o eliminar una propiedad, pero no para modificar su valor. También funciona delante de paréntesis ( ) para comprobar si existe un método y delante de corchetes [ ] para acceder a una propiedad mediante su nombre.
Operador this : Sirve para hacer referencia al objeto actual. Se usa para poder utilizar las propiedades de un objeto desde los métodos de mismo. También se puede usar en funciones para que cuando estas sean añadidas a un objeto puedan acceder a las propiedades del mismo.
Operador new : Sirva para declarar un objeto a partir de una función constructora de objetos. Si no tenemos una función constructora propia, podemos usar la función constructora del objeto O<span style="font-size: 1em;">bject()</span>. Para crear objetos básicos no se suele utilizar en favor de declarar los objetos con un objeto literal vacío { }.
let usuario_objetoLiteral = {};
let usuario_funcionConstructora = new Object();
Las funciones constructoras utilizan this para hacer referencia al objeto que se creará al llamarlas mediante el operador new. También llevan un return implícito que devuelve el objeto recién creado. Las funciones constructoras también pueden llevar referencias a funciones. Por convención, se deben nombrar con la primera letra en mayúscula. Si no se va a reutilizar la función constructora, se puede abreviar como una función anónima.
function Alumno(nombre){
this.nombre = nombre,
this.modulo = "LMSGI",
this.saludo = function(nombre="Buenos días"){
return `${nombre} ${this.nombre}`
}
}
let alumno1 = new Alumno("Paco");
console.log(alumno1.saludo()); // Buenos días Paco
let alumno2 = new Alumno("María");
console.log(alumno2.saludo("Hola")); // Hola María
Operador delete : Sirve para eliminar una propiedad. Hay que tener en cuenta que se pueden leer, añadir o eliminar las propiedades del objeto en cualquier momento. No solo cuando se declaran.
let persona = {nombre: "María"};
persona.apellidos="Martínez";
console.log(persona); // {nombre: "María", apellidos: "Martínez"}
delete persona.nombre;
console.log(persona); // {apellidos: "Martínez"}
Operador in : Sirve para comprobar si una propiedad determinada existe dentro de un objeto. Devuelve un valor booleano: true o false.
const claveBuscada = "direccion";
const alumno = {
nombre : "Paco",
modulo : "LMSGI",
"matricula activa": true,
};
console.log("nombre" in alumno); // true
console.log(claveBuscada in alumno); // false
Operador instanceof : Sirve para comprobar si un objeto es de un tipo de objeto determinado. Hay que recordar que todos los objetos son hijos del objeto genérico Object. Para los tipos de datos primitivos no funciona, en esos casos podemos utilizar typeof.
let num = 5
let texto = "hola"
let notas = [1,2,3,4,5]
let evaluacion = {LMSGI: 8, BD : 6}
// función constructora
function Persona(nombre) {
this.nombre=nombre;
}
let persona = new Persona("Paco");
// Tipo primitivo
console.log(typeof num); // number
console.log(num instanceof Object); // false
console.log(num instanceof Number); // false
// Tipo primitivo
console.log(typeof texto); // string
console.log(texto instanceof Object); // false
console.log(texto instanceof String); // false
// Objeto propio de Javascript
console.log(typeof notas); // object
console.log(notas instanceof Object); // true
console.log(notas instanceof Array); // true
// Objeto declarado por nosotros.
console.log(typeof evaluacion); // object
console.log(evaluacion instanceof Object); // true
// Objeto declarado por nosotros.
console.log(typeof persona); // object
console.log(persona instanceof Persona); // true
console.log(persona instanceof Object); // true
A partir de ECMAScript 6 2015, en el caso de que tengamos una estructura de datos compleja como un objeto o un array, podemos asignar los elementos de estas estructuras directamente a variables individuales sin tener que realizar un bucle para recorrerla. Si la estructura es un objeto, utilizaremos las llaves { } =. Si la estructura es iterable como un array o una cadena de texto, utilizaremos los corchetes [ ] =.
Cuando extraemos propiedades y métodos de un objeto, tenemos que indicar el identificador de esa propiedad o método en las llaves. Para un mejor manejo podemos renombrar las propiedades o métodos con : nombre e incluso darles un valor por defecto con = "valor por defecto". Podemos extraer propiedades no primitivas de un objeto directamente anidando asignaciones con desectructuración, es decir, anidando llaves y/o corchetes.
Operador de propagación (Spread operator) ... : Este operador sirve para expandir una estructura de datos iterable en sus elementos individuales. Nos permite, por ejemplo, copiar todos los elementos individuales de una estructura a otra sin tener que copiarlos de uno en uno.
En el siguiente enlace de la web de MDN puedes ampliar información sobre el operador de propagación de Javascript.
Las sentencias de selección nos permiten bifurcar el código por varios caminos diferentes dependiendo de ciertas condiciones.
Las instrucciones de selección son: if, selección ternaria ... ? ... : ... y switch.
if ... else if ... else
let nota=Math.floor(Math.random()*10);
if (nota < 5) {
console.log("Suspenso");
} else if (nota < 7) {
console.log("Aprobado");
} else if (nota < 9) {
console.log("Notable");
} else {
console.log("Sobresaliente");
}
? ... : ...
let edad = prompt("¿Edad?",18);
let mayorEdad = (edad >= 18) ? alert("Mayor de edad") : alert("Menor de edad")
let edad = Math.random()*65;
let mayorEdad = (edad >= 18) ? true : false;
console.log("Mayor de edad: ", mayorEdad );
// Es equivalente. Se puede asignar el resultado de la condición
let mayorEdad2 = (edad >= 18)
console.log("Mayor de edad: ", mayorEdad2);
switch
switch (diaSemana) {
case "lunes":
alert("Comienza la semana");
break;
case "martes":
case "miércoles":
case "jueves":
case "viernes":
alert("A media semana");
break;
case "sábado":
case "domingo":
alert("Fin de semana");
break;
default:
alert("Día de la semana no reconocido");
}
En los siguientes enlaces de la web de MDN puedes seguir ampliando información sobre el uso de <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else" target="_blank" title="Haz click aquí para ir a la página de MDN." class="html" rel="noopener">if ... else</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_operator" target="_blank" title="Haz click aquí para ir a la página de MDN." class="html" rel="noopener">operador ternario (? ... : ...)</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch" target="_blank" title="Haz click aquí para ir a la página de MDN." class="html" rel="noopener">switch</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/break" target="_blank" title="Haz click aquí para ir a la página de MDN." class="html" rel="noopener">break</a> y <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/continue" target="_blank" title="Haz click aquí para ir a la página de MDN." class="html" rel="noopener">continue</a>
Los bucles for se utilizan cuando sabe de antemano el número de iteraciones que debe hacer el bucle o tenemos una variable o propiedad que conoce ese número de iteraciones.
for
let numero = Math.floor(Math.random()*10);
console.log(`Tabla del ${numero}`)
for (let i=1; i<=10;i++){
console.log(`${i} x ${numero} = ${i*numero}`)
}
for ... of: Sirve para recorrer las estructura iterables como los array y las cadenas de texto.
let notas = [4, 6, 5, 9];
console.log("Notas de LM")
for (let nota of notas){
console.log(`Nota: ${nota}`)
}
for ... in: Sirve para recorrer todos los identificadores de un objeto.
let notas = {"BBDD": 4, "LM": 6, "PRO": 5, "SSII":9};
console.log("Notas de DAW")
for (let clave in notas){
console.log(`Módulo ${clave} nota: ${notas[clave]}`)
}
Los bucles while se utilizan cuando no sabemos de antemano el número de iteraciones que debe hacer un bucle. Es importante que dentro del bucle se modifique alguna de las variables que intervienen en la condición del bucle. De no ser así, el nuestro script se podría bloquear indefinidamente.
while
let numRepeticiones = prompt("¿Cuántas repeticiones?",3)
let repeticion = 0;
while (repeticion<numRepeticiones) {
repeticion++;
console.log(`Repetición ${repeticion}`)
}
Los bucles do ... while se utilizan como los bucles while, con la salvedad de que menos se realizará una iteración del bucle. Esto es debido a que la condición va en el cierre del bucle en lugar de ir en la parte inicial.
do ... while
let continuar;
let repeticion = 1;
do {
console.log(`Repetición ${repeticion}`)
repeticion++;
continuar = confirm("¿Continuar el bucle?")
} while (continuar)
En los siguientes enlaces de la web de MDN puedes seguir ampliando información sobre el uso de <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for" target="_blank" title="Haz click aquí para ir a la página de MDN." class="html" rel="noopener">for</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in" target="_blank" title="Haz click aquí para ir a la página de MDN." class="html" rel="noopener">for ... in</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of" target="_blank" title="Haz click aquí para ir a la página de MDN." class="html" rel="noopener">for ... of</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while" target="_blank" title="Haz click aquí para ir a la página de MDN." class="html" rel="noopener">while</a> y <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/do...while" target="_blank" title="Haz click aquí para ir a la página de MDN." class="html" rel="noopener">do ... while</a>
Las funciones son trozos de código que realizan una determinada tarea. Cuando esta tarea se repite a lo largo de nuestro código, lo primero que se nos ocurriría sería repetir las instrucciones de esa tarea por todo el código. Esta estrategia nos acarrearía muchos problemas. El primero es que nuestro código sería mayor y el segundo y más importante es que si quisiéramos modificar esa tarea tendríamos que modificarla en todos y cada uno de los lugares donde hemos copiado ese código.
La mejor forma de abordar esta situación sería crear una función con el código de dicha tarea. A esta función le asignaríamos un identificador y la llamaríamos en todos los lugares en donde quisiéramos realizar dicha tarea.
En ocasiones estas tareas requieren de alguna información. Esta información se la pasaríamos a la función en el mismo momento en que la llamáramos mediante parámetros.
A continuación se muestran algunos ejemplos de declaraciones y llamadas de funciones en Javascript.
Declaración normal:
function operar(oper, ope1, ope2){
let resultado;
if (oper=="sumar"){
resultado = ope1 + ope2
} if (oper=="restar") {
resultado = ope1 - ope2
}
return resultado;
}
let miFuncion = operar;
let resultado
resultado = operar("sumar", 10, 3);
console.log("El resultado es: ",resultado)
resultado = miFuncion("restar", 10, 3);
console.log("El resultado es: ",resultado)
Notas: Una función se puede asignar a una variable (línea 11) y llamar a través del identificador de dicha variable (línea 15).
Declaración como una expresión de función:
const miFuncion = function operar(oper, ope1, ope2){
let resultado;
if (oper=="sumar"){
resultado = ope1 + ope2
} if (oper=="restar") {
resultado = ope1 - ope2
}
return resultado;
}
let resultado
resultado = operar("sumar", 10, 3);
console.log("El resultado es: ",resultado)
resultado = miFuncion("restar", 10, 3);
console.log("El resultado es: ",resultado)
Notas: Se declara una variable miFuncion (línea 1) como una función. Esta función además puede tener otro identificador, operar.
Función Anónima:
let miFuncion = function (oper, ope1, ope2){
let resultado;
if (oper=="sumar"){
resultado = ope1 + ope2
} if (oper=="restar") {
resultado = ope1 - ope2
}
return resultado;
}
let resultado
resultado = miFuncion("sumar", 10, 3);
console.log("El resultado es: ",resultado)
Notas: El identificador que usábamos en el ejemplo anterior, operar, no es necesario. Por eso le llamamos función anónima.
Función Flecha: Expresión de función anónima abreviada
let miFuncion = (oper, ope1, ope2) => {
let resultado;
if (oper=="sumar"){
resultado = ope1 + ope2
} if (oper=="restar") {
resultado = ope1 - ope2
}
return resultado;
}
let resultado
resultado = miFuncion("sumar", 10, 3);
console.log("El resultado es: ",resultado)
Notas Con la función fecha abreviamos el término function y añadimos una flecha entre los paréntesis y las llaves. Si solo hay un parámetro se pueden quitan los paréntesis. Si no hay parámetros hay que poner unos paréntesis vacíos.
Métodos. Funciones en objetos:
let alumno = {
nombre : "Paco",
modulo : "LMSGI",
"matricula activa": false,
matricular : function (){
this["matricula activa"]=true;
},
// Versión abreviada de un método
desMatricular() {
this["matricula activa"]=false;
}
};
function promocionar(){
console.log("El alumno ha promocionado")
}
console.log(`Nombre del alumno: ${alumno.nombre}`);
console.log(`Estado de la matrícula:. ${alumno["matricula activa"]}`);
alumno.matricular();
console.log(`Estado de la matrícula:. ${alumno["matricula activa"]}`);
alumno.desMatricular();
console.log(`Estado de la matrícula:. ${alumno["matricula activa"]}`);
alumno.promocionar = promocionar;
alumno.promocionar();
Notas:
Línea 5: Declaramos el método matricular como una función anónima. Línea 9: Declaramos el método de forma más abreviada, quitando : function de lo que debería ser una función anónima. Línea 23: Podemos añadir métodos en cualquier momento, no solo cuando declaramos el objeto. Añadimos el método promocionar y como valor le indicamos el identificador de la función de la línea 13.
A partir de ECMAScript 6 2015, se introduce ESM (ECMAScript Module) que permite la importación y exportación de datos entre diferentes archivos Javascript. Un módulo es un archivo con código Javascript que queremos compartir y reutilizar.
Para exportar antepondremos la palabra reservada export a las declaraciones. También podemos usar export { ... } para añadir elementos a la exportación posteriormente a sus declaraciones.
Por ejemplo:
export let nombre = "Paco";
export const saludo = function(nombre="Paco"){
return <code>Hola ${nombre} }; let deportes = ["Natación","Atletismo"] let notas = {LMSGI: [8, 4, 6], BBDD: [5, 7] } export {deportes as aficiones, notas}
Para importarlo, primero tenemos que añadir un elemento HTML script e indicar con el atributo type que es un módulo con type="module". A continuación, dentro de nuestro código Javascript utilizamos las palabras reservadas import { ... } from ...
Si el código del ejemplo anterior lo guardamos en un archivo llamado app.js podríamos trabajar con él desde nuestro archivo HTML de la siguiente forma:
<script type="module">
import {saludo, aficiones, notas as evaluacion} from "./app.js";
console.log(saludo("María"))
console.log(aficiones)
console.log(evaluacion)
</script>
El objeto String se utiliza para representar y manipular cadenas de caracteres.
A continuación se muestra un ejemplo con algunos de sus métodos:
let texto = "En un lugar de la Mancha";
let texto2 = new String("nombre");
let texto3 = `de cuyo ${texto2} no quiero acordarme`;
console.log(texto); //En un lugar de la Mancha
console.log(texto3); //de cuyo nombre no quiero acordarme
console.log(texto.length); // 24
console.log(texto[8]); // g
texto[15]="L"; // INMUTABLE. No se puede modificar.
console.log(texto); //En un lugar de la Mancha
console.log(texto.at(8)); // g
console.log(texto.charAt(8)); // g
console.log(texto.indexOf("g")); // 8
console.log(texto.lastIndexOf("n")) // 20
console.log(texto.includes("lugar")); // true
console.log(texto.startsWith("En")); // true
console.log(texto.endsWith("En")); // false
console.log(texto.search("de")); //12
console.log(texto.match(/a/gi)); // ['a', 'a', 'a', 'a']
console.log(texto.slice(6, 11)); // lugar
console.log(texto.substring(6, 11)); // lugar
console.log(texto.substr(6, 5)); // lugar
console.log(texto.replace("lugar","sitio")); // En un sitio de la Mancha
console.log(texto.split(" ")); // ['En', 'un', 'lugar', 'de', 'la', 'Mancha']
for (let letra of texto.concat(" "+texto3)){
console.log(letra)
}
Juan ya tiene unos conocimientos básicos de Javascript, ha estado trabajando con las variables, con los objetos, conoce las instrucciones selectivas y repetitivas básicas y construye sus pequeñas funciones. Pero ahora se pregunta como modifico una página web.
Ana le comenta que puede modificarla con Javascript, pero él no lo tiene claro.
Javascript es como otros lenguajes de programación. Lo que ha aprendido hasta ahora es lo típico de otros lenguajes de programación. Ana le explica que Javascript tiene una serie de objetos para modelar las páginas web. El navegador por cada página web crea una estructura en árbol con la información que se necesita para su manipulación.
Ahora lo tiene claro. Necesita entender como trabajar con Javascript y poder manejar esa estructura de árbol.
Cuando un navegador carga una página web, crea un modelo de objetos del documento, es decir, va recorriendo el archivo HTML y va creando un nodo del árbol por cada elemento que va encontrando. No solamente crea nodos de los elementos propiamente dichos, también los crea del !DOCTYPE, de los comentarios, de los atributos, de los textos, etc. En la especificación del DOM , existen varios tipos de nodos, los más usados son:
Nodo de tipo<a href="https://dom.spec.whatwg.org/#element" target="_blank" title="Haz click aquí para ir a la página de WHATWG." rel="noopener" class="html">Element</a>
Nodo de tipo<a href="https://dom.spec.whatwg.org/#attr" target="_blank" title="Haz click aquí para ir a la página de WHATWG." rel="noopener" class="html">Attr</a>
En el gráfico anterior puedes ver los nodos Elemento de color amarillo, los nodos Atributo de color azul, el nodo Comentario de color verde y los nodos de Texto de color rojo.
Aunque inicialmente la estandarización del DOM de HTML estaba dirigida por World Wide Web Consortium - W3C, en la actualidad, al igual que la estandarización de HTML, se lleva a cabo por la Web Hypertext Application Technology Working Group - WHATWG.
Inicialmente, Javascript se creó para ser usado en los navegadores web, en la actualidad también se puede utilizar en los servidores web, en aplicaciones de escritorio, en aplicaciones de dispositivos móviles e incluso aplicaciones IoT.
Cuando trabajamos en un navegador web y ejecutamos un script, tenemos una serie de objetos disponibles para su manipulación.
Existe un objeto window por cada ventana o pestaña del navegador. Este objeto a su vez tiene acceso a la API de Javascript y una serie de objetos incluidos en sus propiedades.
Los objetos a los que tenemos acceso desde window los podemos engloban en tres áreas: DOM, BOM y API Javascript.
Modelo de Objetos del Documento (DOM): El modelo de objetos del documento hace una representación de todo el contenido de una página web mediantes objetos Javascript en una estructura de árbol. El elemento raíz de dicho árbol es el objeto document.
Modelo de Objetos del Navegador (BOM): El modelo de objetos del navegador representa mediante objetos las características y propiedades del navegador. Tiene objetos como: navegator, location, screen, etc.
API Javascript: Contiene todos los objetos del lenguaje de programación Javascript que podemos utilizar, como pueden ser: Object, Array, etc.
Cuando un navegador carga una página web que contiene scripts de Javascript este lo hace en dos fases:
En la primera fase, se lee el archivo HTML y todos los archivos a los que hace referencia, ejecutando los scripts en el orden en el que van apareciendo. En esta fase se crea el modelo de objetos del documento.
En una segunda fase, el navegador queda a la espera de que se produzcan eventos para ejecutar el código que le hayamos asignado. Esta ejecución dirigida por eventos es lo que hace las páginas web dinámicas e interactivas.
En Javascript podemos estar a la espera de que ocurran ciertos eventos y en el momento en el que ocurran ejecutar cierto código o función.
Ejemplos de eventos que se producen en el navegador:
Cuando hacemos clic con el ratón.
Cuando pasamos el ratón por encima de un elemento.
Cuando una página web se carga.
Cuando una imagen termina de cargarse.
Cuando el cuadro de texto de un formulario cambia.
Cuando enviamos un formulario.
Cuando se pulsa una tecla.
Podemos asignar código Javascript a un evento de distintas formas, pero la más actual y la que se recomienda es mediante el método addEventListener(). Es la única en la que podemos asignar más de una función manejadora a un evento. De manera que nos permite atomizar mejor las funcionalidades que queremos aplicar a los distintos eventos. Ya que podemos asignar más de una función manejadora de un evento, necesitamos de un método para eliminar estas funciones. Para ello tenemos el método removeEventListener().
Podemos asociar una función al método addEventListener() del evento correspondiente:
<h1 id="demo">Haz clic en este título</h1>
<script>
function modificarTitulo(evento) {
evento.target.innerHTML = "Hola mundo";
}
document.getElementById("demo").addEventListener("click",modificarTitulo);
</script>
También podríamos asociar una función anónima para hacerlo más corto, pero en este caso no podríamos usar el método removeEventListener(), ya que no tendríamos un identificador de función para pasárselo como parámetro al método.
<h1 id="demo">Haz clic en este título</h1>
<script>
document.getElementById("demo").addEventListener("click", function (evento){
evento.target.innerHTML = "Hola mundo";
}
);
</script>
Al método addEventListener() podemos asignarle un objeto en lugar de una función. En el objeto que le pasamos como parámetro deberemos implementar el método handleEvent() que será el encargado de manejar el evento.
Otra forma de manejar eventos, que ha quedado obsoleta, es escribir el código directamente o asociar una función en el atributo HTML correspondiente. Por ejemplo, el atributo HTML onclick.
<h1 onclick="this.innerHTML = 'Hola mundo'">Haz clic en este título</h1>
<h1 onclick="modificarTitulo(this)">Haz clic en este título</h1>
<script>
function modificarTitulo(elemento) {
elemento.innerHTML = "Hola mundo";
}
</script>
Como en el caso anterior, pero de forma dinámica mediante Javascript, podemos asociar una función a la propiedad HTML DOM del evento correspondiente. Por ejemplo: con la propiedad .onclick. El resultado sería el mismo que en el caso anterior y tampoco se recomienda su uso.
<h1 id="demo">Haz clic en este título</h1>
<script>
document.getElementById("demo").onclick = function (evento) {
evento.target.innerHTML = "Hola mundo";
}
</script>
<h1 id="demo">Haz clic en este título</h1>
<script>
document.getElementById("demo").onclick = modificarTitulo;
function modificarTitulo(evento) {
evento.target.innerHTML = "Hola mundo";
}
</script>
No se debe utilizar el método setAttribute() para asociar un manejador a un atributo HTML que corresponda con un evento. Los parámetros del método setAttribute() son cadenas de texto, por lo que el manejador se referenciará a una cadena de texto y no a una función. El valor del atributo HTML será undefined.
.type: cadena de texto con el tipo de evento. Por ejemplo: click, mouseover, mouseout, keydown, keyup, submit, focus, DOMContentLoaded, etc.
.currentTarget: elemento que causó el evento. En la jerarquía de propagación de eventos nos devolverá el elemento en el que usamos el método addEventListener(). Es equivalente a usar this.
.target: elemento que causó el evento. En la jerarquía de propagación de eventos nos devolverá el elemento donde se produjo el evento.
Cuando un navegador tiene una ventana o pestaña abierta, crea un objeto window. Este objeto window contiene al objeto document sobre el que se creará el modelo de objetos del documento. Todos los objetos, funciones y variables del lenguaje Javascript estarán accesible al objeto window. Hay que tener en cuenta que todas las variables y funciones globales que se declaran en Javascript al estar declaradas en el ámbito del objeto window serán accesibles. Es decir, una variable global declarada en cualquier elemento HTML script o en cualquier archivo .js de una página web compartirán ámbito, no podrán compartir identificador y serán accesibles. Es decir, todo el código Javascript de una ventana o pestaña comparten el mismo espacio de nombres. Esto hay que tenerlo en cuenta, ya que tendemos a pensar en el script que estamos desarrollando en un determinado momento y no revisamos el resto de script de esa página web. Por este motivo, en Javascript hay que evitar, en la medida de lo posible, declarar variables de forma global.
Existen otros objetos del modelo de objetos de navegador (BOM) como pueden ser: navegator, screen, location, history, cookies.
El objeto window posee tres métodos que nos brinda cierta interacción con el navegador:
alert(): Nos permite mostrar un mensaje informativo al usuario. En la ventana emergente solo aparecerá un botón aceptar. Más información dealert().
confirm(): Nos permite mostrar un mensaje y pedir confirmación. En la ventana emergente aparecerán dos botones, uno para aceptar y otro para cancelar. El método devuelve verdadero si se pulsa Aceptar y falso si se pulsa Cancelar. Más información de confirm().
prompt(): Nos permite mostrar un mensaje, escribir texto de un cuadro de texto y pedir confirmación. En la ventana emergente aparecerán dos botones, uno para aceptar y otro para cancelar. Como segundo parámetro podemos poner el valor por defecto que aparecerá en el cuadro de texto. El método devuelve verdadero si se pulsa Aceptar y falso si se pulsa Cancelar. Más información de prompt().
Es el objeto window el que contiene a document. Puedes tener dudas porque normalmente usamos directamente document.xxxx y obviamos poner window.document.xxxx.
El objeto document representa toda la información HTML de la página web. Se utiliza para acceder a cualquier elemento de la página web. Es el objeto raíz del árbol DOM.
Para mejorar la accesibilidad a ciertos elementos iguales, el objeto document los agrupa en una serie de colecciones. A estas colecciones se accede mediante una propiedad. Ejemplos de algunas de estas propiedades que agrupan elementos iguales en colecciones son: cookie, forms, images, links y scripts. Estas colecciones las podemos recorrer y podemos acceder a ellas con la notación de Array.
Por ejemplo: document.links[0], elemento.links[1], ...
Además, si alguno de los elementos de la colección tiene un identificador (atributo HTML id) también podremos acceder mediante el valor de dicho identificador como si de un objeto literal o diccionario se tratase. De modo que podríamos acceder como en el siguiente ejemplo:
Algunos de los métodos más usados de estos objetos son: getElementById(), querySelector(), createElement(), createAttribute(), createComment(), addEventListener(), normalize() y hasFocus().
En el siguiente enlace de la web de MDN puedes ampliar información sobre el objeto <a href="https://developer.mozilla.org/es/docs/Web/API/Document" target="_blank" title="Haz click aquí para ir a la página de MDN." class="html" rel="noopener">document</a>.
En este otro enlace puedes ver otra lista de los métodos y atributos del objeto <a href="https://www.w3schools.com/jsref/dom_obj_document.asp" target="_blank" title="Haz click aquí para ir a la página de W3Schools" rel="noopener" class="html">document</a>.
Existe un objeto para representar cada elemento HTML, por ejemplo: HTMLImageElement, HTMLAnchorElement, HTMLTableElement, HTMLFormElement, etc.
Todos estos objetos derivan un elemento genérico llamado HTMLElement. Este objeto además hereda de otro más genérico llamando Element y este a su vez de otro más genérico aún llamado Node. Gracias a esta herencia, conociendo los métodos y las propiedades de estos objetos genéricos podremos utilizar los objetos más específicos de una forma más homogénea.
Algunos de los métodos más usados en estos objetos son: addEventListener(), contains(), focus(), blur(), getAttribute(), innerHTML, matches(), normalize(), querySelector(), remove(), removeAttribute(), removeEventListener(), setAttribute() y toString()
Algunas de sus propiedades más usadas son: attributes, children, classList, className, innerHTML, nodeName, nodeType, nodeValue, outerHTML, parentNode, parentElement, style, tagName y title
La propiedad attributes almacena los atributos HTML de un elemento. Utiliza una estructura NamedNodeMap para almacenarlos. La propiedad children almacena los elementos hijos de un elemento. Utiliza una estructura HTMLCollection para almacenarlos.
Las propiedades attributes y children las podemos recorrer y acceder a ellas tanto con la notación de array [ ] como con la notación de objeto literal o diccionario [ ]. En el caso de la propiedad children, en la notación diccionario, utilizaríamos los nombres de sus atributos HTML id. Para la propiedad attributes utilizaríamos el nombre HTML de su atributo.
Hay que tener en cuenta que existen ciertos objetos que tienen algunas propiedades específicas que no poseen sus objetos padres, como por ejemplo:
HTMTAnchorElement que tiene la propiedad: href
HTMLTableElement que tiene las propiedades: row, caption
HTMLTableRowElement que tiene la propiedad: cells
HTMLInputElement que tiene la propiedad: type
HTMLInputElement, HTMLSelectElement o HTMLTextareaElement que tiene la propiedad: value.
Ya veremos más adelante que la forma usual de acceder a un elemento y a sus atributos no será recorriendo estas propiedades children y attributes, sino que directamente los buscaremos mediante un selector CSS, un id, una clase, etc.
Por ejemplo con: document.querySelector("#miElemento").
La primera funcionalidad que necesitamos para trabajar con el modelo de objetos del documento (DOM) es poder seleccionar los elementos que queremos manipular. Recordamos que el DOM tiene estructura de árbol y desplazarnos por él no es tan sencillo como movernos en una estructura de Array. Lo más común es que necesitemos localizar un elemento determinado y que dicho elemento lo hayamos marcado en nuestro código HTML con un atributo HTML id determinado. Si lo que necesitamos localizar es a un conjunto de elementos homogéneos, a estos los habríamos marcado con un atributo HTML class.
Los métodos recomendados para localizar uno o varios elementos son los siguientes:
querySelector(): Busca un elemento HTML que cumpla con un determinado selector CSS. En caso de que haya varios que cumplan con el selector CSS indicado, devolverá el primero que encuentre. Devuelve un solo elemento de tipo Element.
querySelectorAll(): Busca todos los elementos HTML que cumplan con un determinado selector CSS. Devuelve los elementos encontrados en una estructura estática de tipo NodeList. Si usamos querySelectorAll("selectorCSS")[0] nos devolvería lo mismo que querySelector("selectorCSS").
Para realizar una búsqueda en todo el documento debemos llamar a estos métodos desde el objeto document. Se pueden usar desde otros elementos, pero la búsqueda se restringiría a dicho elemento y sus descendientes.
Gracias a los selectores CSS, los métodos querySelector() y querySelectorAll() son muy flexibles y permiten hacer búsquedas más exhaustivas que no permiten otros métodos que veremos más adelante, por ejemplo: div.tarjeta>img. Además, podemos localizar pseudoclases CSS como :hover o :active.
Un método útil cuando trabajamos con selectores CSS sería:
matches(): Comprueba si el elemento sería seleccionado por el selector CSS indicado. Devuelve verdadero o falso.
Existen otros métodos que se usaban anteriormente y que en algunos casos también pueden llegar a ser útiles, estos métodos de selección y acceso a elementos son:
getElementById(): busca un elemento HTML por el atributo HTML id. Devuelve un solo elemento de tipo Element. Este método debe ser llamado desde el objeto document para que la búsqueda se realice en todo el documento.
getElementsByClassName(): busca todos los elementos HTML que tengan el atributo HTML class indicado. Devuelve los elementos encontrados en una estructura de tipo HTMLCollection.
getElementsByName(): busca todos los elementos HTML que tengan el atributo HTML name indicado. Se suele usar con los elementos de los formularios que utilizan el atributo name para nombrar los valores de los componentes de los formularios en las respuestas HTML. Devuelve los elementos encontrados en una estructura de tipo NodeList.
getElementsByTagName(): busca todos los elementos HTML que tengan la etiqueta indicada. Si se le pasa la cadena asterisco "*" buscará cualquier etiqueta. Devuelve los elementos encontrados en una estructura de tipo HTMLCollection.
Aunque no suele ser lo habitual, puede darse el caso que necesitemos desplazarnos por los nodos que forman el árbol DOM. Para ello disponemos de las siguientes propiedades: parentNode, childNodes, firstChild, lastChild, previousSibling, nextSibling.
Puedes ampliar la información de las propiedades del objetoNode.
En caso de que necesitemos desplazarnos solamente a través de los elementos, es decir, los nodos de tipo Element, dispondremos de las siguientes propiedades: parentElement, children, firstElementChild, lastElementChild, previousElementSibling, nextElementSibling, childElementCount.
Puedes ampliar la información de las propiedades del objetoElement.
Una colección HTMLCollection es una colección de datos para almacenar objetos HTMLElement. Cuenta con la propiedad .length y los métodos:
item(): que devuelve el elemento de la posición indicada. Se puede abreviar y acceder mediante un índice, es decir, en formato Array [ ].
namedItem(): devuelve el elemento indicado por el atributo HTML id o name. Se puede abreviar y acceder mediante el formato objeto literal o diccionario [ ].
Puedes ver más información sobre la estructuraHTMLCollection.
Una lista NodeList es una lista para almacenar objetos Node. Cuenta con la propiedad .length y los métodos:
item(): que devuelve el elemento de la posición indicada. Se puede abreviar y acceder mediante un índice, es decir, en formato Array [ ].
forEach(): utilidad que facilita recorrer la lista en un bucle indicando una función en lugar del contenido del bucle.
keys(): Va devolviendo los identificadores de la lista de uno en uno cuando recorremos el bucle for.
values(): Va devolviendo los valores de la lista de uno en uno cuando recorremos el bucle for.
entries(): Va devolviendo las parejas identificador-valor de la lista de uno en uno cuando recorremos un bucle for.
Puedes ver más información sobre esta estructuraNodeList.
// NodeList
const misElementos_NL = document.querySelectorAll("p");
//console.log(misElementos_NL.namedItem("uno")) // TypeError: misElementos_NL.namedItem is not a function
console.log(misElementos_NL["uno"]) //undefined
console.log(misElementos_NL.item(0))
console.log(misElementos_NL[0])
Para recorrer ambas estructuras podemos hacerlo mediante un bucle for normal o mejor con un bucle for ... of.
Estas estructuras, aunque se parezcan a Arrays no lo son. Si quisiéramos usar algún método de la clase Array como filter() podemos transformarlos a un Array con la función Array.from(). Puedes ver más información sobre la funciónArray.from().
//HTMLCollection
const misElementos = document.getElementsByTagName("*");
// bucle for normal
for (let i = 0; i < misElementos.length; i++) {
...
}
// bucle for..of
for (let elemento of misElementos) {
...
}
// transformación a un Array con Array.from
miElementosArray = Array.from(misElementos)
// NodeList
const misElementos = document.querySelectorAll("*");
// bucle for normal
for (let i = 0; i < misElementos.length; i++) {
...
}
// bucle for..of
for (let elemento of misElementos) {
...
}
// bucle for..each
misElementos.forEach(function mostrar(elemento) { console.log(elemento)});
misElementos.forEach((elemento) => console.log(elemento));
// transformación a un Array con Array.from
miElementosArray = Array.from(misElementos)
Las diferencias entre HTMCollection y NodeList son:
HTMCollection almacena objetos HTMElement y NodeList objetos Node.
HTMCollection puede ser accedida mediante los atributos HTML id, name y por posición. NodeList solo puede ser accedido por la posición.
HTMCollection son colecciones dinámicas y NodeList son colecciones estáticas.
NodeList puede utilizar el método ForEach() directamente.
Existe una serie de métodos que nos ayudan a crear nuevos nodos en el árbol DOM. Podemos crear nodos de los distintos tipos, los más habituales son: nodos elemento, nodos comentario y nodos de texto:
createElement(): Crea un elemento del tipo indicado. Se le debe indicar la etiqueta del elemento a crear. Crea el elemento pero no lo añade al árbol DOM.
createComment(): Crea un nuevo nodo de comentarios. Crea el comentario pero no lo añade al árbol DOM.
createTextNode(): Crea un nuevo nodo de texto. Crea el Texto pero no lo añade al árbol DOM.
Otros métodos y propiedades de utilidad cuando creamos nodos son:
isConnected: Propiedad que indica si un nodo está conectado o no al árbol DOM, es decir, al objeto document. Toma los valores verdadero o falso.
cloneNode(): Clona un nodo y devuelve una copia. Si se le indica verdadero true como parámetro la clonación será también de sus nodos descencientes.
contains(): Comprueba si el nodo indicado es un nodo descendiente: hijo, hijo de uno de sus hijos, etc. Devuelve verdadero o falso.
En ocasiones necesitamos modificar varios elementos de una página web. Cada vez que cambiamos algo en el árbol DOM este se suele volver a renderizar en nuestro navegador. Esto puedo ocasionar que la página web no se vea fluida y no responda adecuadamente. Para solucionar este problema podemos crear fragmentos de documento DocumentFragment. Estos fragmentos de documento son una especie de objetos document mínimos que no tienen elemento padre. Su manejo es más liviano y no afectan al refresco del navegador.
En el siguiente enlace de la web de MDN puedes ampliar información sobre el objeto <a href="https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment" target="_blank" title="Haz click aquí para ir a la página de MDN." class="html" rel="noopener">DocumentFragment</a> de Javascript.
Tenemos una serie de propiedades que nos facilitan información de los nodos que hemos creado, estas propiedades son:
.nodeName: Propiedad de solo lectura que almacena el nombre del nodo. Sirve para cualquier nodo, no solo para los nodos de tipo Elemento. En los nodos que no tienen identificadores devuelve un texto asociado, por ejemplo en los nodos de tipo texto devuelve #text y en los nodos de tipo comentario devuelve #comment.
.nodeValue: Propiedad que almacena el contenido de un nodo. Si el nodo es de tipo Elemento, su contenido será vacío, ya que este tipo de nodos utilizan la propiedad .innerHTML. La propiedad .NodeValue se utiliza para el resto de nodos: como los nodos de tipo Texto o los nodos de tipo Comentario.
.data: Propiedad similar a la anterior.
.tagName: Propiedad que almacena el nombre de la etiqueta. Solo sirve para los nodos de tipo Elemento.
A la hora de trabajar con el contenido de los nodos de tipo Elemento utilizaremos las siguientes propiedades:
.textContent: Propiedad que almacena el contenido textual del elemento y de sus elementos hijos. Se puede modificar. Es el método recomendado para trabajar con el contenido textual de un elemento, ya que trata todos los caracteres y símbolos de forma literal.
.innerHTML: Propiedad que almacena el contenido HTML del elemento en forma de cadena de texto. Incluye los elementos hijos y sus etiquetas. Se puede modificar. Este método se suele utilizar para introducir pequeños trozos de código HTML y contenido textual sin tener utilizar el método createElement(). Si a esta propiedad se le asigna código HTML con errores, el navegador tratará de corregirlo, por lo que puede haber diferencias entre lo asignado a la propiedad y lo que se almacena en la propiedad.
.outerHTML: Igual que la propiedad anterior, pero añade las etiquetas de apertura y cierre del propio elemento. Esta propiedad modifica el árbol DOM, pero no actualiza las variables Javascript, es decir, veremos las modificaciones en el navegador, pero en memoria la variable contendrá los valores anteriores. Para solucionarlo tendremos que recargar las variables con los nuevos valores, es decir, asignarle otra vez el valor del árbol DOM, por ejemplo con document.querySelector().
Con los métodos y propiedades que hemos visto hasta ahora podemos crear nodos de los tipos más habituales y darles contenido. El siguiente paso sería añadir dichos nodos al modelo de objetos del documento o árbol DOM.
Podemos añadir los nodos desde tres puntos de vista:
Como elementos,
Por adyacencias
Como nodos.
Inserción como elementos en el árbol DOM:
before(): Añade uno o varios nodos justo antes del elemento. Se le puede pasar nodos o cadenas de texto que se convertirán en nodos de tipos texto.
after(): Añade uno o varios nodos justo después del elemento. Se le puede pasar nodos o cadenas de texto que se convertirán en nodos de tipos texto.
prepend(): Añade uno o varios nodos justo antes del primer hijo del elemento. Se le puede pasar nodos o cadenas de texto que se convertirán en nodos de tipos texto.
append(): Añade uno o varios nodos justo después del último hijo del elemento. Se le puede pasar nodos o cadenas de texto que se convertirán en nodos de tipos texto.
replaceChildren(): Elimina todos los hijos y los sustituye por el nuevo o los nuevos nodos. Se le puede pasar nodos o cadenas de texto que se convertirán en nodos de tipos texto.
replaceWith(): Sustituye el elemento por el nuevo o los nuevos nodos. Se le puede pasar nodos o cadenas de texto que se convertirán en nodos de tipos texto.
remove(): Elimina el propio elemento. Realmente el elemento no desaparece, lo que sucede es que se desconecta del árbol de nodos. Hay que tener en cuenta que si lo que queremos es mover un elemento no hace falta eliminarlo. Cuando lo insertamos en un nuevo lugar desaparece de su anterior ubicación. O mejor dicho, se desconecta de tu anterior ubicación.
Todos estos métodos añaden nodos o cadenas de texto que se transforman en nodos de texto. Si les pasamos como parámetro, una cadena de texto con etiquetas HTML las insertará como texto, tal y como se hace con la propiedad .textContent. Es decir, de una forma segura.
Inserción de elementos por adyacencia en el árbol DOM:
Los métodos siguientes permiten insertar código HTML, elementos o texto en la posición indicado en su primer parámetro. Es decir, en un solo método tenemos toda la funcionalidad de los métodos before(), after(), prepend() y append(). Este primer parámetro puede tomar alguno de los siguientes valores:
beforebegin: Inserta el elemento antes de la etiqueta HTML de apertura. Es equivalente al método: before()
afterbegin: Inserta el elemento dentro, antes de su primer hijo. Es equivalente al método: prepend()
beforeend: Inserta el elemento dentro, justo antes de la etiqueta HTML de cierre. Es equivalente a los métodos: append() o appendChild()
afterend: Inserta el elemento después de la etiqueta HTML de cierre. Es equivalente al método: after()
Los métodos de inserción por adyacencia son:
insertAdjacentHTML(): inserta texto o código HTML en la posición indicada de su primer parámetro. Con este método podemos insertar una cadena de texto con código HTML y que este funcione como tal, con un funcionamiento semejante a la propiedad .innerHTML.
insertAdjacentElemennt(): inserta un elemento en la posición indicada de su primer parámetro.
insertAdjacentText(): inserta el texto en la posición indicada de su primer parámetro. Este método insertará la cadena de texto como un nodo de texto. Si la cadena de texto tuviese código HTML este no sería funcional. Su funcionamiento es semejante a la propiedad .textContent.
Los siguientes métodos no se suelen usar, ya que los que hemos visto anteriormente son más versátiles. Pero aún se pueden encontrar en páginas web más antiguas.
appendChild(): Añade un nodo como último hijo. Devuelve el nodo insertado.
removeChild(): Elimina y devuelve el nodo eliminado.
replaceChild(): Reemplaza el nodo indicado por el nuevo nodo. Devuelve el nodo antiguo.
insertBefore(): Inserta el nodo antes del nodo hijo indicado. Si se indica null como nodo hijo, el nuevo nodo se insertará como último nodo, de forma equivalente al método appendChild().
El objeto Attr son parejas de nombre del atributo y su valor que se usan para representar los atributos estándar de los elementos HTML. Tienen las propiedades .name y .value que se corresponden con el nombre del atributo y su valor.
Cuando se recorre la página web para crear el modelo de objetos del documento, si un elemento HTML tiene uno o varios atributos, estos se almacenan en la propiedad .attributes del elemento. Esta propiedad es de tipo NamedNodeMap, es decir, una secuencia de objetos Attr que almacenan parejas: nombre de atributo y valor.
Además, si son atributos HTML estándar, crea propiedades de objeto con los nombres de estos atributos estándar. De modo que también podemos acceder a los valores de los atributos HTML estándar como si fueran propiedades del objeto.
Por ejemplo, si tenemos una variable miImagen que contiene un elemento HTML img, podemos acceder a tu atributo src con: miImagen.src.
Atributos HTML no estándar: Cuando queremos crear un atributo personalizado podemos hacerlo anteponiéndole el texto data-. Todos los atributos que comienzan con data- están reservados para el uso de los programadores. Son accesibles con la propiedad .dataset. Esta propiedad es de tipo DOMStringMap.
Hay que tener en cuenta que un atributo puede ser estándar para un elemento, pero no para otro.
Por ejemplo, el atributo HTML type es estándar para el elemento HTML input pero no para el elemento HTML p.
Un ejemplo de uso podría ser el siguiente:
Si un elemento tiene un atributo HTML llamado data-mensaje-bienvenida, este estará disponible en su propiedad .dataset.mensajeBienvenida.
Puedes tener más información de estos atributos en el siguiente enlace.
Nótese que el segundo guion se convierte en notación camel-case.
La propiedad .attributes es de tipo NamedNodeMap y permite usar su propiedad .length para saber el número de atributos que tenemos. También podemos utilizar los siguientes métodos:
setNamedItem(): añade el nodo a la lista .attributes, indexándolo según su propiedad nodeName.
getNamedItem(): devuelve el nodo con el nombre indicado.
item(): devuelve el nodo que se encuentra en la posición indicada.
removeNamedItem(): elimina el nodo con el nombre indicado.
Existen unos casos especiales de atributos HTML, los atributos class y style. Estos atributos pueden tener muchos valores, por lo que para manejarlos utilizan sus propios métodos y propiedades.
Ya veremos más adelante que como los atributos dependen siempre de un elemento, la forma usual de acceder a ellos no será recorriendo la propiedad .attributes, sino que directamente buscaremos el elemento del que dependa mediante un selector CSS, un identificador, una clase, etc.
Por ejemplo con: document.querySelector("#miId"). Una vez tengamos el elemento en una variable accederemos con los métodos getAttribute() y setAttribute(). Si son atributos estándar del lenguaje HTML, también podremos acceder con la propiedad que se crea con su identificador (nombre del atributo HTML). Por ejemplo: miImagen.src.
En el siguiente enlace puedes ver una lista más completa de los métodos y atributos del objeto <a href="https://www.w3schools.com/jsref/dom_obj_attributes.asp" target="_blank" title="Haz click aquí para ir a la página de W3Schools" rel="noopener" class="html">Attr</a>.
Como ya hemos visto, podemos acceder a los atributos HTML estándar por la propiedad de objeto que se crea al cargar el modelo de objetos del documento. Estas propiedades contienen los atributos en diferentes estructuras de datos: cadenas de texto, booleanos, objetos CSSStyleDeclaration, DOMTokenList, etc.
Otra forma de manejar los atributos HTML estándar y no estándar es mediante los siguientes métodos:
hasAttributes(): Plural. Comprueba si el elemento contiene algún atributo. Devuelve verdadero o falso.
hasAttribute(): Comprueba si el elemento contiene el atributo indicado. Devuelve verdadero o falso.
getAttribute(): Devuelve una cadena de texto con el valor de un atributo del que indicamos su nombre. Es equivalente a attributes.getNamedItem(nombre).
getAttributeNames(): Devuelve una lista de cadenas de texto con los nombres de atributos.
setAttribute(): Establece el nombre y el valor de un atributo en el elemento. Si no existía el atributo lo crea nuevo. Si queremos indicar que es un atributo booleano, pasaremos como parámetros el nombre del atributo y una cadena de texto vacía. Equivalente a: attributes.getNamedItem(nombre).value = valor.
createAttribute(): Crea un nodo atributo. Crea el atributo, pero no lo añade al árbol DOM. Para añadir este nodo atributo deberemos usar el método setAttributeNode(). No se suele usar, en su lugar se usa el método setAttribute() o toggleAttribute() con su segundo parámetro a true.
removeAttribute(): Elimina el atributo indicado. Equivalente a attributes.removeNamedItem(nombre).
toggleAttribute(): Añade o elimina un atributo. Si el atributo existe lo elimina y si no existe lo añade. Tiene un segundo parámetro booleano opcional para indicar si queremos forzar a crear el atributo o queremos forzar a eliminar el atributo. Se utiliza especialmente para los atributos booleanos que son a los que no se le asignan un valor. Si está el nombre del atributo se considera verdadero y si no está el nombre del atributo se considera falso. Hay que tener en cuenta que algunas propiedades que representan atributos HTML estándar almacenan el valor como un booleano y no como una cadena de texto, como suele ser lo habitual. Por ejemplo, la propiedad disabled de los elementos HTML input, con el método getAttribute() nos devolverá una cadena de texto vacía, ya que es un atributo booleano y no tiene valor. Para comprobar dicho atributo debemos acceder a la propiedad .disabled y leer su valor booleano.
Tenemos que tener en cuenta que al indicar el nombre del atributo no se distinguirá entre mayúsculas y minúsculas. Además, al asignarle un valor, tanto los contenidos textuales como los contenidos numéricos se convertirán a cadenas de texto.
En el tratamiento del atributo HTML class tenemos que tener en cuenta algunos detalles. El primero es que la palabra class es una palabra reservada de Javascript para la declaración de clases. Por lo que no debemos usarla para referirnos a las clases CSS, en su lugar usaremos palabras parecidas como className, classList, etc. En segundo lugar, este atributo HTML es usado intensamente para la creación de estilos CSS y suele ser habitual que un elemento HTML tenga asignadas varias clases CSS. Por lo que la complejidad aumente y deberemos manejar de forma individualizada cada una de estas clases.
En el diseño de páginas web suele ser común crear clases CSS con ciertos estilos generales. Después añadimos a los elementos una o varias clases hasta obtener el estilo deseado. Esta forma de trabajar nos permite tener unos estilos básicos que podemos reutilizar más fácilmente.
Para el manejo del atributo HTML class tenemos las siguientes propiedades:
.className: Propiedad que almacena los valores del atributo HTML class del elemento. Esta propiedad es de tipo cadena de texto. Se usa cuando el atributo HTML class solo tiene un valor. Se pueden poner varios valores separados por espacios en blanco, pero para estos casos es mejor usar la propiedad classList. Es equivalente a usar los métodos getAttribute() y setAttribute().
.classList: Similar a la propiedad className pero que almacena los valores del atributo HTML class en una estructura DOMTokenList. Esta propiedad se suele usa cuando el atributo HTML class tiene varios valores. La estructura DOMTokenList tiene una serie de métodos que nos facilitan el manejo de las clases:
.classList.length: propiedad que nos indica el número de clases que tiene el elemento.
.classList.value(): Devuelve todos los valores de la lista de clases en una única cadena de texto.
.classList.add(): añade la clase o clases indicadas.
.classList.remove(): elimina la clase o clases indicadas.
.classList.item(): Devuelve la clase de la posición indicada. Se puede abreviar y acceder mediante un índice, es decir, en formato Array [ ]. Devuelve null si no hay ninguna clase en la posición indicada.
.classList.toggle(): Añade una clase si no está o la elimina si está. Acepta un segundo parámetro opcional para forzar a añadirla si es true o eliminarla si es false. El método devuelve true si, tras ejecutar el método, la clase indicada sigue existiendo y false en caso de que la clase ya no exista en el elemento.
.classList.contains(): Indica si la clase indicada está en el elemento.
.classList.replace(): Reemplaza una clase por otra.
.classList.forEach(): utilidad que facilita recorrer la lista en un bucle indicando una función en lugar del contenido del bucle.
.classList.keys(): Va devolviendo los identificadores de la lista de uno en uno cuando recorremos el bucle for.
.classList.values(): Va devolviendo los valores de la lista de uno en uno cuando recorremos el bucle for.
.classList.entries(): Va devolviendo las parejas identificador-valor de la lista de uno en uno cuando recorremos un bucle for.
Además, la propiedad .classList es iterable, es decir, la podemos recorrer con un bucle for...of. También la podríamos convertir a un Array con el método Array.from().
Pueden existir casos en los que no queramos trabajar con clases y necesitemos trabajar directamente sobre el estilo de un elemento en concreto. Recordad que esta forma de trabajar no nos permite reutilizar estilos CSS ya creados, sino que tendremos que repetirlos en todos y cada uno de los elementos en los que los necesitemos.
El atributo HTML style al ser un atributo estándar cuando el modelo de objetos del documento recorre la página web, crea una propiedad de objeto llamada con el nombre del atributo, es decir .style. Por ejemplo: miElemento.style. Cabe resaltar que esta propiedad es de solo lectura. La propiedad .style se almacena en un objeto CSSStyleDeclaration, dicho objeto tiene una serie de propiedades y métodos para facilitar su manejo:
.style.length: propiedad que nos indica el número de declaraciones CSS que tiene el atributo HTML style.
.style.cssText: propiedad que nos da acceso a la representación textual de los valores de dicho atributo. Esta propiedad se puede modificar. No se suele utilizar esta propiedad, ya que sobreescribe el contenido anterior. Su uso sería al crear un nuevo elemento que quisiéramos que incluyese varias propiedades CSS a la vez y trabajarlas con una única cadena de texto. Es equivalente a usar setAttribute("style","...propiedades CSS...").
.style.getPropertyValue(): método que nos devuelve el valor de la propiedad CSS indicada.
.style.setProperty(): método que modifica o añade una propiedad CSS. Si no existía la añade.
.style.removeProperty(): método que elimina la propiedad CSS indicada.
.style.item(): método que nos devuelve el nombre de la propiedad CSS indicada por su posición. Se puede abreviar y acceder mediante un índice, es decir, en formato Array [ ].
Como las propiedades CSS también son estándar, el modelo de objetos del documento también las añade como propiedades de objeto con los nombres de dichas propiedades CSS. Por ejemplo: miElemento.style.backgroundColor. Para asignarle un valor utilizaríamos por ejemplo: miElemento.style.backgroundColor="red".
En caso de que quisiéramos eliminar esa propiedad CSS deberemos asignarle una cadena de texto vacía, es decir: miElemento.style.backgroundColor="" o utilizar el método removeProperty(), como en el ejemplo: miElemento.style.removeProperty(backgroundColor).
En general se suele utilizar más el acceso mediante propiedades de objeto que mediante las propiedades y métodos de CSSStyleDeclaration. Esas propiedades y métodos se suelen utiliza cuando queremos recorrer todas las propiedades CSS y no queremos indicar el nombre de la propiedad.
Si nos fijamos en el ejemplo miElemento.style.backgroundColor, la nomenclatura de los estilos CSS de Javascript difiere de la habitual de CSS.
Por ejemplo, en CSS escribimos la propiedad para el color de fondo como, background-color, pero en Javascript la escribiremos como backgroundColor. Es decir, cambiando los guiones por la siguiente letra en mayúsculas. A este estilo de escritura, muy usado en Javascript, se le llamacamel-case.
Hay que tener en cuenta que la propiedad .style almacena los valores de dicho atributo. Pero solo los valores declarados con el atributo HTML style del elemento. No contendrá otros valores declarados sobre el mismo elemento en otros elementos style del head o en hojas de estilos externas.
Materiales desarrollados inicialmente por el Ministerio de Educación, Cultura y Deporte y actualizados por el profesorado de la Junta de Andalucía bajo licencia Creative Commons BY-NC-SA.
Antes de cualquier uso leer detenidamente el siguenteAviso legal