One place for hosting & domains

      clases

      Cómo modificar atributos, clases y estilos en el DOM


      Introducción

      En el tutorial anterior de esta serie, “Cómo realizar cambios en el DOM”, abordamos la forma de crear, insertar, sustituir y eliminar elementos del Document Object Model (DOM) con métodos incorporados. Al aumentar su competencia en el manejo del DOM, podrá usar mejor las capacidades interactivas de JavaScript y modificar elementos web.

      En este tutorial aprenderemos a cambiar más el DOM modificando estilos, clases y otros atributos de nodos de elementos HTML. Esto le permitirá comprender mejor la manera de manipular elementos esenciales dentro del DOM.

      Revisión de la selección de elementos

      Hasta hace poco, una biblioteca popular de JavaScript llamada jQuery se usaba muy a menudo para seleccionar y modificar elementos del DOM. jQuery simplificó el proceso de selección de uno o varios elementos y aplicación de cambios en todos ellos al mismo tiempo. En “Cómo acceder a elementos del DOM”, revisamos los métodos del DOM para capturar nodos y trabajar con ellos en Vanilla JavaScript.

      Para la revisión, document.querySelector() y document.getElementById() son los métodos utilizados para acceder a un único elemento. Usando un div con un atributo id en el siguiente ejemplo, podemos acceder a ese elemento de cualquier forma.

      <div id="demo-id">Demo ID</div>
      

      El método querySelector() es más sólido, ya que puede seleccionar un elemento en la página a través de cualquier tipo de selector.

      // Both methods will return a single element
      const demoId = document.querySelector('#demo-id');
      

      Accediendo a un único elemento, podemos actualizar fácilmente una parte del elemento, como el texto interno.

      // Change the text of one element
      demoId.textContent = 'Demo ID text updated.';
      

      Sin embargo, al acceder a varios elementos a través de un selector común, como una clase específica, debemos repetir todos los elementos de la lista. En el siguiente código, tenemos dos elementos div con un valor de clase común.

      <div class="demo-class">Demo Class 1</div>
      <div class="demo-class">Demo Class 2</div>
      

      Utilizaremos querySelectorAll() para capturar todos los elementos con demo-class que se les aplicaron y forEach() para repetirlos y aplicar un cambio. También es posible acceder a un elemento específico con querySelectorAll() de la misma forma que con una matriz: usando una notación entre paréntesis.

      // Get a NodeList of all .demo elements
      const demoClasses = document.querySelectorAll('.demo-class');
      
      // Change the text of multiple elements with a loop
      demoClasses.forEach(element => {
        element.textContent = 'All demo classes updated.';
      });
      
      // Access the first element in the NodeList
      demoClasses[0];
      

      Es una de las diferencias más importantes que se deben tener en cuenta al pasar de jQuery a Vanilla JavaScript. Muchos ejemplos de modificación de elementos no explicarán el proceso de aplicación de esos métodos y propiedades a varios elementos.

      A menudo, las propiedades y los métodos de este artículo se adjuntarán a escuchas de eventos para responder a clics, desplazamientos u otros activadores.

      Nota: Los métodos getElementsByClassName() y getElementsByTagName() mostrarán colecciones HTML que no tienen acceso al método forEach() que querySelectorAll() tiene. En estos casos, deberá usar un bucle estándar for la repetición en la colección.

      Modificación de atributos

      Los atributos son valores que contienen información adicional sobre elementos HTML. Normalmente vienen en pares de nombre y valor, y pueden ser esenciales según elemento.

      Algunos de los atributos HTML más comunes son el atributo src de una etiqueta img, el href de una etiqueta a, class, id y style. Para obtener una lista completa de atributos HTML, consulte la lista de atributos en la Mozilla Developer Network. Los elementos personalizados que no formen parte del estándar HTML se prefijarán con data-.

      En JavaScript, tenemos cuatro métodos para modificar atributos de elementos:

      Método Descripción Ejemplo
      hasAttribute() Muestra un booleano true o false. element.hasAttribute('href');
      getAttribute() Muestra el valor de un atributo especificado o null. element.getAttribute('href');
      setAttribute() Agrega o actualiza el valor de un atributo especificado. element.setAttribute('href', 'index.html');
      removeAttribute() Elimina un atributo de un elemento. element.removeAttribute('href');

      Crearemos un nuevo archivo HTML con una etiqueta img con un atributo. Estableceremos un vínculo a una imagen pública disponible a través de una URL, pero puede cambiarla por una imagen local alternativa si trabaja sin conexión.

      attributes.html

      <!DOCTYPE html>
      <html lang="en">
      <body>
      
          <img src="https://js-tutorials.nyc3.digitaloceanspaces.com/shark.png">
      
      </body>
      
      </html>
      

      Cuando cargue el archivo HTML anterior en un navegador web moderno y abra la consola para desarrolladores integrada, verá algo como lo siguiente:

      Primera representación de classes.html

      Ahora podemos probar todos los métodos de atributos sobre la marcha.

      // Assign image element
      const img = document.querySelector('img');
      
      img.hasAttribute('src');                // returns true
      img.getAttribute('src');                // returns "...shark.png"
      img.removeAttribute('src');             // remove the src attribute and value
      

      En este punto, habrá eliminado el atributo src y el valor asociado con img, pero puede reiniciar ese atributo y asignar el valor a una imagen alternativa con img.setAttribute():

      img.setAttribute('src', 'https://js-tutorials.nyc3.digitaloceanspaces.com/octopus.png');
      

      Segunda representación de classes.html

      Por último, podemos modificar el atributo directamente asignándole un nuevo valor como una propiedad del elemento, haciendo que el src vuelva al archivo shark.png.

      img.src = 'https://js-tutorials.nyc3.digitaloceanspaces.com/shark.png';
      

      Cualquier atributo puede editarse de esta forma y también con los métodos anteriores.

      Los métodos hasAttribute() y getAttribute() se utilizan normalmente con instrucciones condicionales y los métodos setAttribute() y removeAttribute() se usan para modificar directamente el DOM.

      Modificación de clases

      El atributo de class corresponde a los selectores de clase de CSS. No se debe confundir con las clases ES6, un tipo especial de función de JavaScript.

      Las clases CSS se utilizan para aplicar estilos a varios elementos, a diferencia de los ID que solo pueden existir una vez por página. En JavaScript, contamos con las propied className y classList para trabajar con el atributo de clase.

      Método/Propiedad Descripción Ejemplo
      className Obtiene o establece un valor de clase. element.className;
      classList.add() Agrega uno o más valores de clase. element.classList.add('active');
      classList.toggle() Activa o desactiva una clase. element.classList.toggle('active');
      classList.contains() Comprueba si el valor de clase existe. element.classList.contains('active');
      classList.replace() Sustituye un valor de clase existente por uno nuevo. element.classList.replace('old', 'new');
      classList.remove() Elimina un valor de clase. element.classList.remove('active');

      Crearemos otro archivo HTML para que funcione con los métodos de clase, con dos elementos y algunas clases.

      classes.html

      <!DOCTYPE html>
      <html lang="en">
      
      <style>
          body {
              max-width: 600px;
              margin: 0 auto;
              font-family: sans-serif;
          }
          .active {
              border: 2px solid blue;
          }
      
          .warning {
              border: 2px solid red;
          }
      
          .hidden {
              display: none;
          }
      
          div {
              border: 2px dashed lightgray;
              padding: 15px;
              margin: 5px;
          }
      </style>
      
      <body>
      
          <div>Div 1</div>
          <div class="active">Div 2</div>
      
      </body>
      
      </html>
      

      Cuando abra el archivo classes.html en un navegador web, debería recibir una representación similar a la siguiente:

      Primera representación de classes.html

      La propiedad className se introdujo para evitar conflictos con la palabra clave de class que se encuentra en JavaScript y otros lenguajes que tienen acceso al DOM. Puede utilizar className para asignar un valor directamente a la clase.

      // Select the first div
      const div = document.querySelector('div');
      
      // Assign the warning class to the first div
      div.className = 'warning';
      

      Hemos asignado la clase warning definida en los valores CSS de classes.html al primer div. Obtendrá el siguiente resultado:

      Segunda representación de classes.html

      Tenga en cuenta que si ya hay clases en el elemento, esto las anulará. Puede agregar varias clases delimitadas por espacios usando la propiedad className o usarla sin los operadores de asignación para obtener el valor de la clase en el elemento.

      La otra forma de modificar clases es a través de la propiedad classList, que incluye algunos métodos útiles. Dichos métodos son similares a los de addClass, removeClass y toggleClass de jQuery.

      // Select the second div by class name
      const activeDiv = document.querySelector('.active');
      
      activeDiv.classList.add('hidden');                // Add the hidden class
      activeDiv.classList.remove('hidden');             // Remove the hidden class
      activeDiv.classList.toggle('hidden');             // Switch between hidden true and false
      activeDiv.classList.replace('active', 'warning'); // Replace active class with warning class
      

      Tras aplicar los métodos anteriores, su página web tendrá este aspecto:

      Renderización final de classes.html

      A diferencia del ejemplo de className, al utilizarse classList.add() se añadirá una nueva clase a la lista existente. También puede agregar varias clases como cadenas separadas por comas. También es posible utilizar setAttribute para modificar la clase de un elemento.

      Modificación de estilos

      La propiedad de estilo representa los estilos incorporados en un elemento HTML. A menudo, se aplicarán estilos a elementos a través de una hoja de estilos como lo hemos hecho antes en este artículo, pero a veces debemos agregar o editar un estilo alineado directamente.

      Haremos un breve ejemplo para mostrar estilos de edición con JavaScript. A continuación, se muestra un nuevo archivo HTML con un div que tiene algunos estilos incorporados para mostrar un cuadrado.

      styles.html

      <!DOCTYPE html>
      <html lang="en">
      
      <body>
      
          <div style="height: 100px;
                      width: 100px;
                      border: 2px solid black;">Div</div>
      
      </body>
      
      </html>
      

      Cuando se abra en un navegador web, styles.html tendrá este aspecto:

      Primera representación de styles.html

      Una opción para editar los estilos es setAttribute().

      // Select div
      const div = document.querySelector('div');
      
      // Apply style to div
      div.setAttribute('style', 'text-align: center');
      

      Sin embargo, esto eliminará todos los estilos alineados existentes del elemento. Debido a que este probablemente no sea el efecto deseado, es mejor utilizar el atributo style directamente.

      div.style.height = '100px';
      div.style.width = '100px';
      div.style.border = '2px solid black';
      

      Las propiedades de CSS se escriben en kebab-case, que son palabras minúsculas separadas por guiones. Tenga en cuenta que las propiedades de CSS de kebab-case no se pueden utilizar en la propiedad de estilo de JavaScript. Se sustituirán por su equivalente en camelCase, en el cual la primera palabra se escribe con minúscula y las siguientes con mayúsculas. En otras palabras, en vez de text-align utilizaremos textAlign para la propiedad de estilo de JavaScript.

      // Make div into a circle and vertically center the text
      div.style.borderRadius = '50%';
      div.style.display = 'flex';
      div.style.justifyContent = 'center';
      div.style.alignItems = 'center';
      

      Tras completar las modificaciones de estilo anteriores, en su representación final de styles.html se mostrará un círculo:

      Representación final de styles.html

      Si deben aplicarse muchos cambios estilísticos a un elemento, lo mejor es aplicar los estilos a una clase y agregar una nueva clase. Sin embargo, hay algunos casos en los que será necesario o más práctico modificar el atributo de estilo alineado.

      Conclusión

      Los elementos HTML a menudo tienen información adicional asignada en forma de atributos. Los atributos pueden incluir pares de nombre y valor, y algunos de los más comunes son class y style.

      En este tutorial, aprendió a acceder, modificar y eliminar atributos de un elemento HTML del DOM usando JavaScript simple. También aprendió a agregar, eliminar, activar y sustituir clases de CSS en un elemento y editar estilos de CSS alineados. Para obtener más información, consulte la documentación sobre atributos en la Mozilla DeveloperNetwork.



      Source link

      Información sobre clases de JavaScript


      Introducción

      JavaScript es un lenguaje basado en prototipos y cada objeto en él tiene una propiedad interna oculta llamada [[Prototype]] que puede usarse para extender propiedades y métodos de objetos. Puede obtener más información sobre los prototipos de nuestro tutorial Información sobre los prototipos y la herencia en JavaScript.

      Hasta hace poco, los desarrolladores esforzados usaban funciones constructoras para imitar un patrón de diseño orientado a objetos en JavaScript. La especificación de lenguaje ECMAScript 2015, a menudo denominada ES6, introdujo clases en el lenguaje JavaScript. Las clases de JavaScript no ofrecen realmente una funcionalidad adicional y a menudo se describen como elementos que aportan “azúcar sintáctico” en comparación con los prototipos y la herencia, ya que ofrecen una sintaxis más limpia y elegante. Debido a que otros lenguajes de programación usan clases, la sintaxis de clase de JavaScript permite que los desarrolladores alternen lenguajes de forma más directa.

      Las clases son funciones

      Una clase de JavaScript es un tipo de función. Las clases se declaran con la palabra clave class. Usaremos sintaxis de expresión de función para inicializar una sintaxis de expresión de función y clase para inicializar una clase.

      // Initializing a function with a function expression
      const x = function() {}
      
      // Initializing a class with a class expression
      const y = class {}
      

      Podemos acceder a [[Prototype]] de un objeto usando el métodoObject.getPrototypeOf(). Usaremos eso para probar la función vacía que creamos.

      Object.getPrototypeOf(x);
      

      Output

      ƒ () { [native code] }

      También podemos usar ese método en la clase que acabamos de crear.

      Object.getPrototypeOf(y);
      

      Output

      ƒ () { [native code] }

      El código declarado con function y class muestra una función [[Prototype]]. Con prototipos, cualquier función puede convertirse en una instancia de constructor mediane la palabra clave new.

      const x = function() {}
      
      // Initialize a constructor from a function
      const constructorFromFunction = new x();
      
      console.log(constructorFromFunction);
      

      Output

      x {} constructor: ƒ ()

      Esto se aplica a clases también.

      const y = class {}
      
      // Initialize a constructor from a class
      const constructorFromClass = new y();
      
      console.log(constructorFromClass);
      

      Output

      y {} constructor: class

      Estos ejemplos de constructores de prototipos, de lo contrario, están vacíos. Sin embargo, podemos ver que debajo de la sintaxis ambos métodos logran el mismo resultado final.

      Definir una clase

      En el tutorial de prototipos y herencia, confeccionamos un ejemplo basado en la creación de personajes en un juego de roles basado en texto. Continuaremos con ese ejemplo aquí para actualizar la sintaxis de funciones a clases.

      Una función constructora se inicializa con varios parámetros que se asignarían como propiedades de this, en alusión a la propia función. La primera letra del identificador sería mayúscula por convención.

      constructor.js

      // Initializing a constructor function
      function Hero(name, level) {
          this.name = name;
          this.level = level;
      }
      

      Cuando traducimos esto a la sintaxis de clase, que se muestra a continuación, vemos que su estructura es bastante similar.

      class.js

      // Initializing a class definition
      class Hero {
          constructor(name, level) {
              this.name = name;
              this.level = level;
          }
      }
      

      Sabemos que una función constructora está pensada para ser un esquema de objeto por el uso de mayúscula en la primera letra del inicializador (opcional) y a través de la familiaridad con la sintaxis. La palabra clave class comunica de una manera más directa el objetivo de nuestra función.

      La única diferencia en la sintaxis de la inicialización tiene que ver con el uso de la palabra clave class en lugar de function, y con la asignación de las propiedades dentro de un método constructor().

      Definir métodos

      La práctica común con funciones constructoras consiste en asignar métodos directamente a prototype en lugar de hacerlo con la initialización, como se aprecia en el método greet() a continuación.

      constructor.js

      function Hero(name, level) {
          this.name = name;
          this.level = level;
      }
      
      // Adding a method to the constructor
      Hero.prototype.greet = function() {
          return `${this.name} says hello.`;
      }
      

      Con clases, esta sintaxis se simplifica y el método puede agregarse directamente a las clases. Al usar la abreviatura de definición de método introducida en ES6, se logra una concisión aun mayor al definir un método.

      class.js

      class Hero {
          constructor(name, level) {
              this.name = name;
              this.level = level;
          }
      
          // Adding a method to the constructor
          greet() {
              return `${this.name} says hello.`;
          }
      }
      

      Observemos estas propiedades y métodos en acción. Crearemos una nueva instancia de Hero usando la palabra clave new y asignaremos algunos valores.

      const hero1 = new Hero('Varg', 1);
      

      Si imprimimos más información sobre nuestro nuevo objeto con console.log(hero1), podemos apreciar más detalles sobre lo que sucede con la inicialización de clase.

      Output

      Hero {name: "Varg", level: 1} __proto__: ▶ constructor: class Hero ▶ greet: ƒ greet()

      Podemos ver en el resultado que las funciones constructor() y greet() se aplicaron a __proto__, o [[Prototype]] de hero1, y no directamente como método en el objeto hero1. Aunque esto queda de manifiesto en la creación de funciones de constructor, no resulta evidente al crear clases. Las clases permiten una sintaxis más sencilla y sucinta, aunque sacrifican algo de claridad en el proceso.

      Ampliar una clase

      Una característica ventajosa de las funciones y clases constructoras es que pueden ampliarse a nuevos esquemas de objeto basados en el elemento principal. Esto impide la repetición de código para objetos similares, pero necesitan características adicionales o más específicas.

      Se pueden crear nuevas funciones constructoras desde el elemento principal usando el método call(). En el siguiente ejemplo, crearemos una clase de carácter más específica llamada Mage y le asignaremos las propiedades de Hero usando call(), además de agregar una propiedad.

      constructor.js

      // Creating a new constructor from the parent
      function Mage(name, level, spell) {
          // Chain constructor with call
          Hero.call(this, name, level);
      
          this.spell = spell;
      }
      

      En este punto, podemos crear una nueva instancia de Mage usando las mismas propiedades de Hero, así como también una nueva que agregamos.

      const hero2 = new Mage('Lejon', 2, 'Magic Missile');
      

      Al enviar hero2 a la consola, podemos apreciar que creamos una nueva clase Mage basada en la constructora.

      Output

      Mage {name: "Lejon", level: 2, spell: "Magic Missile"} __proto__: ▶ constructor: ƒ Mage(name, level, spell)

      Con clases de ES6, la palabra clave super se usa en lugar de call para acceder a las funciones principales. Usaremos extends para hacer referencia a la clase principal.

      class.js

      // Creating a new class from the parent
      class Mage extends Hero {
          constructor(name, level, spell) {
              // Chain constructor with super
              super(name, level);
      
              // Add a new property
              this.spell = spell;
          }
      }
      

      Ahora podemos crear una nueva instancia de Mage de la misma manera.

      const hero2 = new Mage('Lejon', 2, 'Magic Missile');
      

      Imprimiremos hero2 en la consola y veremos el resultado.

      Output

      Mage {name: "Lejon", level: 2, spell: "Magic Missile"} __proto__: Hero ▶ constructor: class Mage

      El resultado es casi exactamente el mismo, con la diferencia de que en la construcción de clase [[Prototype]] se vincula al elemento principal; en este caso, Hero.

      A continuación, se muestra una comparación en paralelo de todo el proceso de inicialización, incorporación de métodos y herencia de una función constructor y una clase.

      constructor.js

      function Hero(name, level) {
          this.name = name;
          this.level = level;
      }
      
      // Adding a method to the constructor
      Hero.prototype.greet = function() {
          return `${this.name} says hello.`;
      }
      
      // Creating a new constructor from the parent
      function Mage(name, level, spell) {
          // Chain constructor with call
          Hero.call(this, name, level);
      
          this.spell = spell;
      }
      

      class.js

      // Initializing a class
      class Hero {
          constructor(name, level) {
              this.name = name;
              this.level = level;
          }
      
          // Adding a method to the constructor
          greet() {
              return `${this.name} says hello.`;
          }
      }
      
      // Creating a new class from the parent
      class Mage extends Hero {
          constructor(name, level, spell) {
              // Chain constructor with super
              super(name, level);
      
              // Add a new property
              this.spell = spell;
          }
      }
      

      Aunque la sintaxis es bastante distinta, el resultado subyacente es casi el mismo para ambos métodos. Las clases nos ofrecen una alternativa más concisa para crear esquemas de objeto y las funciones constructor describen con mayor precisión lo que sucede en segundo plano.

      Conclusión

      En este tutorial, incorporó conocimientos sobre las similitudes y diferencias entre las funciones constructor de JavaScript y las clases de ES6. Tanto las clases como las funciones constructor imitan un modelo de herencia orientado hacia objetos para JavaScript, que es un lenguaje de herencia basado en prototipos.

      Comprender la herencia prototípica es primordial para desempeñarse con eficacia como desarrollador de JavaScript. Familiarizarse con las clases es extremadamente útil, ya que en las bibliotecas de JavaScript populares como React se usa con frecuencia la sintaxis class.



      Source link