Mira la lección en vídeo
Accede al vídeo completo de esta lección y a más contenido exclusivo con el Plan Plus.
Desbloquear Plan PlusAlteración de contenido textual: Diferencias entre innerText, textContent y nodeValue
Cuando trabajamos con el DOM, modificar el contenido textual de los elementos es una operación fundamental. JavaScript ofrece tres propiedades principales para manipular texto en elementos: innerText
, textContent
y nodeValue
. Aunque parecen similares, cada una tiene comportamientos específicos que debemos entender para elegir la más adecuada en cada situación.
innerText
La propiedad innerText
representa el contenido de texto visible de un elemento, similar a lo que un usuario vería en la página. Esta propiedad:
- Respeta el estilo CSS aplicado (no muestra elementos ocultos con
display: none
) - Aplica formato básico respetando saltos de línea
- Es sensible al rendimiento, ya que desencadena un recálculo de estilos
// Obtener el texto visible
const heading = document.querySelector('h1');
const visibleText = heading.innerText;
// Modificar el texto visible
heading.innerText = 'New Heading Text';
// innerText ignora elementos ocultos
const div = document.querySelector('div');
div.innerHTML = 'Visible <span style="display: none">Hidden</span> Text';
console.log(div.innerText); // Output: "Visible Text"
textContent
La propiedad textContent
representa todo el contenido textual de un nodo y sus descendientes, independientemente de su visibilidad. Esta propiedad:
- Devuelve el contenido de todos los elementos, incluso los ocultos con CSS
- Preserva espacios en blanco y formato original del código HTML
- Tiene mejor rendimiento que
innerText
al no provocar recálculos de estilo
// Obtener todo el contenido textual
const paragraph = document.querySelector('p');
const allText = paragraph.textContent;
// Modificar todo el contenido textual
paragraph.textContent = 'This replaces all content, including nested elements';
// textContent incluye elementos ocultos
const div = document.querySelector('div');
div.innerHTML = 'Visible <span style="display: none">Hidden</span> Text';
console.log(div.textContent); // Output: "Visible Hidden Text"
nodeValue
La propiedad nodeValue
es diferente a las anteriores y funciona a un nivel más bajo del DOM. Esta propiedad:
- Solo funciona en nodos de texto, comentarios o atributos (no directamente en elementos)
- Requiere acceder primero al nodo de texto específico
- Es más precisa cuando necesitamos manipular un nodo de texto específico
// Para usar nodeValue, primero debemos acceder al nodo de texto
const paragraph = document.querySelector('p');
const textNode = paragraph.firstChild;
// Solo funciona si firstChild es un nodo de texto
if (textNode && textNode.nodeType === Node.TEXT_NODE) {
console.log(textNode.nodeValue); // Muestra el contenido del nodo de texto
textNode.nodeValue = 'Modified text content';
}
Comparación práctica
Veamos un ejemplo que ilustra las diferencias entre estas propiedades:
// Creamos un elemento con contenido mixto
const container = document.createElement('div');
container.innerHTML = `
Visible text
<span style="display: none">Hidden text</span>
<script>const x = 1;</script>
`;
console.log(container.innerText); // "Visible text"
console.log(container.textContent); // "Visible text\n Hidden text\n const x = 1;"
// Para nodeValue necesitamos el nodo de texto específico
const firstTextNode = container.firstChild;
console.log(firstTextNode.nodeValue); // "\n Visible text\n "
Escenarios de uso recomendados
- Usa
innerText
cuando necesites obtener o establecer el texto visible tal como aparece en la página. - Usa
textContent
cuando necesites todo el contenido textual sin importar la visibilidad, o por razones de rendimiento. - Usa
nodeValue
cuando necesites manipular con precisión un nodo de texto específico dentro de un elemento.
Consideraciones de seguridad
A diferencia de innerHTML
, estas tres propiedades tratan el contenido como texto plano, lo que las hace seguras contra ataques XSS (Cross-Site Scripting):
// Seguro: el código HTML se muestra como texto, no se ejecuta
const userInput = '<script>alert("XSS Attack")</script>';
element.textContent = userInput; // Se muestra como texto: <script>alert("XSS Attack")</script>
La elección entre estas propiedades dependerá del contexto específico de tu aplicación y de si necesitas preservar o ignorar elementos ocultos, mantener o eliminar formato, o manipular nodos de texto específicos.
Gestión de atributos personalizados y dataset: Almacenamiento de metadatos en elementos
Los elementos HTML no solo contienen contenido visible, sino que también pueden almacenar metadatos adicionales que enriquecen su funcionalidad sin afectar su presentación. JavaScript ofrece mecanismos para gestionar estos datos a través de atributos personalizados y la interfaz dataset, permitiéndonos asociar información relevante directamente a los elementos del DOM.
Atributos estándar vs personalizados
Los elementos HTML tienen atributos estándar como id
, class
o src
, pero a menudo necesitamos almacenar información adicional específica para nuestra aplicación:
// Acceso a atributos estándar
const link = document.querySelector('a');
console.log(link.href); // https://example.com
console.log(link.getAttribute('href')); // https://example.com
// Modificación de atributos estándar
link.href = 'https://mozilla.org';
// Alternativa:
link.setAttribute('href', 'https://mozilla.org');
Para información personalizada, podemos usar atributos personalizados que siguen la convención data-*
:
<button data-role="submit" data-user-id="123" data-permission="admin">
Enviar formulario
</button>
Manipulación de atributos con getAttribute y setAttribute
Los métodos getAttribute()
y setAttribute()
permiten trabajar con cualquier tipo de atributo, incluyendo los personalizados:
const button = document.querySelector('button');
// Lectura de atributos personalizados
const role = button.getAttribute('data-role'); // "submit"
const userId = button.getAttribute('data-user-id'); // "123"
// Modificación de atributos personalizados
button.setAttribute('data-status', 'pending');
button.setAttribute('data-user-id', '456');
// Verificación de existencia de atributos
const hasPermission = button.hasAttribute('data-permission'); // true
// Eliminación de atributos
button.removeAttribute('data-status');
La interfaz dataset: acceso simplificado
La propiedad dataset
proporciona una forma más elegante y directa de acceder a los atributos data-*
, convirtiéndolos automáticamente en propiedades de un objeto JavaScript:
const button = document.querySelector('button');
// Acceso a través de dataset (notación camelCase)
console.log(button.dataset.role); // "submit"
console.log(button.dataset.userId); // "123" (data-user-id se convierte a camelCase)
console.log(button.dataset.permission); // "admin"
// Modificación a través de dataset
button.dataset.status = 'processing';
button.dataset.timestamp = Date.now();
// Eliminación de atributos data
delete button.dataset.status;
Observa cómo los nombres de atributos con guiones (data-user-id
) se convierten automáticamente a camelCase (dataset.userId
).
Casos de uso prácticos
Los atributos personalizados y dataset son especialmente útiles para:
- Almacenar identificadores relacionados con datos de backend:
// Lista de productos con IDs para operaciones AJAX
const productList = document.querySelector('.products');
productList.addEventListener('click', (event) => {
if (event.target.matches('.product')) {
const productId = event.target.dataset.productId;
fetchProductDetails(productId);
}
});
- Configuración de componentes sin necesidad de JavaScript adicional:
<div class="carousel" data-auto-play="true" data-interval="5000" data-show-indicators="false">
<!-- Contenido del carrusel -->
</div>
// Inicialización basada en atributos data
document.querySelectorAll('.carousel').forEach(carousel => {
new Carousel(carousel, {
autoPlay: carousel.dataset.autoPlay === 'true',
interval: parseInt(carousel.dataset.interval || 3000),
showIndicators: carousel.dataset.showIndicators !== 'false'
});
});
- Estado de la interfaz de usuario para elementos interactivos:
const toggleButton = document.querySelector('.toggle-button');
toggleButton.addEventListener('click', () => {
// Cambiar entre estados usando dataset
if (toggleButton.dataset.state === 'active') {
toggleButton.dataset.state = 'inactive';
toggleButton.textContent = 'Activar';
} else {
toggleButton.dataset.state = 'active';
toggleButton.textContent = 'Desactivar';
}
});
Consideraciones importantes
- Los valores en
dataset
siempre se almacenan como cadenas de texto. Para valores numéricos o booleanos, necesitarás realizar la conversión:
// Conversión de tipos al leer valores
const count = parseInt(element.dataset.count, 10);
const isEnabled = element.dataset.enabled === 'true';
const config = JSON.parse(element.dataset.config || '{}');
-
Los atributos
data-*
son visibles en el HTML, por lo que no son adecuados para información sensible. -
Los cambios en
dataset
se reflejan inmediatamente en el DOM y viceversa:
// Los cambios son bidireccionales
element.dataset.status = 'active';
console.log(element.getAttribute('data-status')); // "active"
element.setAttribute('data-priority', 'high');
console.log(element.dataset.priority); // "high"
- Puedes usar atributos personalizados como selectores CSS:
/* Estilizar elementos basados en atributos data */
button[data-role="submit"] {
background-color: green;
}
.product[data-stock="0"] {
opacity: 0.5;
}
Los atributos personalizados y la interfaz dataset
proporcionan una forma estructurada y semántica de asociar metadatos a elementos DOM, facilitando la creación de interfaces dinámicas sin necesidad de mantener estados separados en variables JavaScript.
Estrategtas para cambios visuales dinámicos
AI:
Manipulación de cly estilos: Estratestas para cambios visuales dinámicos
Guarda tu progreso
Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.
Más de 25.000 desarrolladores ya confían en CertiDevs
La manipulación de clases y estilos es fundamental para crear interfaces dinámicas y responsivas. JavaScript ofrece varias formas de modificar la apariencia de los elementos HTML, cada una con sus propias ventajas.
Manipulación de clases CSS
La interfaz classList
proporciona métodos poderosos para gestionar las clases CSS de un elemento, ofreciendo una alternativa más limpia y eficiente que manipular directamente el atributo className
.
const card = document.querySelector('.card');
// Añadir clases
card.classList.add('highlighted', 'active');
// Eliminar clases
card.classList.remove('disabled');
// Alternar clases (añade si no existe, elimina si existe)
card.classList.toggle('expanded');
// Verificar si un elemento tiene una clase específica
if (card.classList.contains('editable')) {
enableEditMode();
}
// Reemplazar una clase por otra
card.classList.replace('loading', 'loaded');
La interfaz classList
es más eficiente que manipular directamente className
, ya que evita tener que parsear y reconstruir cadenas de texto:
// Enfoque antiguo (menos recomendado)
if (!element.className.includes('active')) {
element.className += ' active';
}
// Enfoque moderno con classList (recomendado)
element.classList.add('active');
Manipulación directa de estilos
Para cambios de estilo específicos, podemos acceder directamente a la propiedad style
del elemento:
const notification = document.querySelector('.notification');
// Establecer estilos individuales
notification.style.backgroundColor = '#e74c3c';
notification.style.color = 'white';
notification.style.transform = 'translateY(-20px)';
notification.style.transition = 'all 0.3s ease';
// Las propiedades CSS con guiones se convierten a camelCase
notification.style.borderRadius = '4px';
notification.style.boxShadow = '0 2px 10px rgba(0,0,0,0.2)';
Esta técnica es ideal para cambios dinámicos basados en interacciones del usuario o datos variables:
// Cambiar el ancho de una barra de progreso basado en un porcentaje
function updateProgressBar(percent) {
const progressBar = document.querySelector('.progress-bar');
progressBar.style.width = `${percent}%`;
// Cambiar color basado en el progreso
if (percent < 30) {
progressBar.style.backgroundColor = '#e74c3c'; // rojo
} else if (percent < 70) {
progressBar.style.backgroundColor = '#f39c12'; // naranja
} else {
progressBar.style.backgroundColor = '#2ecc71'; // verde
}
}
Aplicando múltiples estilos
Para aplicar varios estilos a la vez, podemos usar cssText
o la API Object.assign()
:
// Usando cssText para múltiples estilos
element.style.cssText = 'color: white; background-color: #3498db; padding: 10px; border-radius: 4px;';
// Alternativa usando Object.assign()
Object.assign(element.style, {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '200px',
backgroundColor: '#9b59b6'
});
Accediendo a estilos computados
Para obtener los estilos actuales aplicados a un elemento (incluyendo los de hojas de estilo):
const element = document.querySelector('.box');
const styles = window.getComputedStyle(element);
console.log(styles.backgroundColor);
console.log(styles.fontSize);
console.log(styles.getPropertyValue('margin-left'));
// Para pseudo-elementos
const beforeStyles = window.getComputedStyle(element, '::before');
console.log(beforeStyles.content);
Estrategias para animaciones y transiciones
Las transiciones CSS combinadas con JavaScript ofrecen una forma eficiente de crear animaciones:
function animateElement() {
const box = document.querySelector('.box');
// Configurar la transición antes de cambiar propiedades
box.style.transition = 'transform 0.5s ease-out, opacity 0.5s ease';
// Aplicar los cambios que activarán la transición
box.style.transform = 'scale(1.2) rotate(5deg)';
box.style.opacity = '0.8';
// Restaurar después de la transición
setTimeout(() => {
box.style.transform = 'scale(1) rotate(0)';
box.style.opacity = '1';
}, 2000);
}
Clases vs. estilos inline: ¿Cuándo usar cada uno?
- Uso de clases CSS (recomendado para la mayoría de casos):
- Para cambios que afectan múltiples propiedades
- Cuando los estilos están predefinidos
- Para mantener la separación de responsabilidades
// Cambiar entre estados visuales predefinidos
function toggleDarkMode() {
document.body.classList.toggle('dark-theme');
// También podemos actualizar elementos hijos
document.querySelectorAll('.card').forEach(card => {
card.classList.toggle('dark-card');
});
// Guardar preferencia del usuario
const isDarkMode = document.body.classList.contains('dark-theme');
localStorage.setItem('darkMode', isDarkMode);
}
- Uso de estilos inline:
- Para valores calculados dinámicamente
- Para animaciones y cambios temporales
- Cuando necesitas precisión absoluta
// Posicionar un tooltip relativo a un elemento
function showTooltip(targetElement, text) {
const tooltip = document.createElement('div');
tooltip.className = 'tooltip';
tooltip.textContent = text;
document.body.appendChild(tooltip);
const rect = targetElement.getBoundingClientRect();
tooltip.style.left = `${rect.left + rect.width / 2 - tooltip.offsetWidth / 2}px`;
tooltip.style.top = `${rect.bottom + 10}px`;
// Mostrar con animación
tooltip.style.opacity = '0';
tooltip.style.transform = 'translateY(-10px)';
tooltip.style.transition = 'all 0.3s ease';
// Forzar reflow para que la transición funcione
tooltip.offsetHeight;
tooltip.style.opacity = '1';
tooltip.style.transform = 'translateY(0)';
}
Técnicas avanzadas: Variables CSS (propiedades personalizadas)
Las variables CSS combinadas con JavaScript permiten crear temas dinámicos y sistemas de diseño flexibles:
// Cambiar tema de color usando variables CSS
function setThemeColor(primaryColor, secondaryColor) {
document.documentElement.style.setProperty('--primary-color', primaryColor);
document.documentElement.style.setProperty('--secondary-color', secondaryColor);
// Guardar preferencias
localStorage.setItem('theme', JSON.stringify({ primary: primaryColor, secondary: secondaryColor }));
}
// Ejemplo de uso
document.querySelector('#theme-selector').addEventListener('change', (e) => {
const theme = e.target.value;
if (theme === 'blue') {
setThemeColor('#3498db', '#2980b9');
} else if (theme === 'green') {
setThemeColor('#2ecc71', '#27ae60');
} else if (theme === 'purple') {
setThemeColor('#9b59b6', '#8e44ad');
}
});
Optimización del rendimiento
Al manipular estilos, es importante considerar el rendimiento:
- Minimiza los reflows: Agrupa los cambios de estilo para reducir recálculos de layout
// Mal (causa múltiples reflows)
element.style.width = '100px';
element.style.height = '100px';
element.style.margin = '10px';
// Mejor (un solo reflow)
element.style.cssText = 'width: 100px; height: 100px; margin: 10px;';
// O usando clases (aún mejor)
element.classList.add('box-dimensions');
- Usa
requestAnimationFrame
para animaciones suaves:
function animateProgress(element, targetWidth) {
let width = 0;
function step() {
width += 2;
element.style.width = `${width}%`;
if (width < targetWidth) {
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);
}
// Uso
animateProgress(document.querySelector('.progress-bar'), 75);
Ejemplo práctico: Sistema de notificaciones
Combinando clases y estilos para crear un sistema de notificaciones dinámico:
function showNotification(message, type = 'info') {
const notification = document.createElement('div');
notification.className = 'notification';
notification.classList.add(`notification-${type}`);
notification.textContent = message;
// Añadir al DOM
document.body.appendChild(notification);
// Forzar reflow antes de añadir clase para activar transición
notification.offsetHeight;
// Mostrar con animación
notification.classList.add('notification-visible');
// Configurar auto-cierre
setTimeout(() => {
notification.classList.remove('notification-visible');
// Eliminar del DOM después de la transición
notification.addEventListener('transitionend', () => {
notification.remove();
});
}, 5000);
// Añadir botón de cierre
const closeBtn = document.createElement('button');
closeBtn.className = 'notification-close';
closeBtn.innerHTML = '×';
closeBtn.addEventListener('click', () => {
notification.classList.remove('notification-visible');
});
notification.appendChild(closeBtn);
return notification;
}
// Ejemplos de uso
document.querySelector('#success-btn').addEventListener('click', () => {
showNotification('Operación completada con éxito', 'success');
});
document.querySelector('#error-btn').addEventListener('click', () => {
showNotification('Ha ocurrido un error', 'error');
});
Con el CSS correspondiente:
.notification {
position: fixed;
bottom: -100px;
right: 20px;
padding: 15px 20px;
border-radius: 4px;
box-shadow: 0 3px 10px rgba(0,0,0,0.2);
transition: transform 0.3s ease, opacity 0.3s ease;
opacity: 0;
transform: translateY(0);
}
.notification-visible {
transform: translateY(-120px);
opacity: 1;
}
.notification-info {
background-color: #3498db;
color: white;
}
.notification-success {
background-color: #2ecc71;
color: white;
}
.notification-error {
background-color: #e74c3c;
color: white;
}
Esta combinación de manipulación de clases y estilos permite crear interfaces dinámicas y responsivas que mejoran significativamente la experiencia del usuario.
AI:
Manipulación de clases y estilos: Estrategias para cambios visuales dinámicos
La manipulación de clases y estilos es una habilidad fundamental para crear interfaces web dinámicas y responsivas. JavaScript ofrece diferentes mecanismos para modificar la apariencia de los elementos HTML, cada uno con sus propias ventajas según el contexto de uso.
Manipulación de clases con classList
La interfaz classList
proporciona métodos intuitivos para gestionar las clases CSS de un elemento, ofreciendo una alternativa más limpia que manipular directamente el atributo className
:
const card = document.querySelector('.card');
// Añadir una o más clases
card.classList.add('highlighted', 'active');
// Eliminar clases
card.classList.remove('disabled');
// Alternar una clase (añade si no existe, elimina si existe)
card.classList.toggle('expanded');
// Verificar si un elemento tiene una clase específica
if (card.classList.contains('editable')) {
enableEditMode();
}
// Reemplazar una clase por otra
card.classList.replace('loading', 'loaded');
Esta API es más eficiente que manipular directamente className
, ya que evita tener que parsear y reconstruir cadenas de texto:
// Enfoque antiguo (menos recomendado)
if (!element.className.includes('active')) {
element.className += ' active';
}
// Enfoque moderno con classList (recomendado)
element.classList.add('active');
Manipulación directa de estilos inline
Para cambios de estilo específicos, podemos acceder a la propiedad style
del elemento:
const notification = document.querySelector('.notification');
// Establecer estilos individuales
notification.style.backgroundColor = '#e74c3c';
notification.style.color = 'white';
notification.style.transform = 'translateY(-20px)';
// Las propiedades CSS con guiones se convierten a camelCase
notification.style.borderRadius = '4px';
notification.style.boxShadow = '0 2px 10px rgba(0,0,0,0.2)';
Esta técnica es ideal para cambios dinámicos basados en interacciones del usuario o datos variables:
// Cambiar el ancho de una barra de progreso según un porcentaje
function updateProgressBar(percent) {
const progressBar = document.querySelector('.progress-bar');
progressBar.style.width = `${percent}%`;
// Cambiar color basado en el progreso
if (percent < 30) {
progressBar.style.backgroundColor = '#e74c3c'; // rojo
} else if (percent < 70) {
progressBar.style.backgroundColor = '#f39c12'; // naranja
} else {
progressBar.style.backgroundColor = '#2ecc71'; // verde
}
}
Aplicando múltiples estilos
Para aplicar varios estilos a la vez, podemos usar cssText
o la API Object.assign()
:
// Usando cssText para múltiples estilos
element.style.cssText = 'color: white; background-color: #3498db; padding: 10px;';
// Alternativa usando Object.assign()
Object.assign(element.style, {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '200px',
backgroundColor: '#9b59b6'
});
Accediendo a estilos computados
Para obtener los estilos actuales aplicados a un elemento (incluyendo los de hojas de estilo):
const element = document.querySelector('.box');
const styles = window.getComputedStyle(element);
console.log(styles.backgroundColor);
console.log(styles.fontSize);
console.log(styles.getPropertyValue('margin-left'));
// Para pseudo-elementos
const beforeStyles = window.getComputedStyle(element, '::before');
console.log(beforeStyles.content);
Estrategias para animaciones y transiciones
Las transiciones CSS combinadas con JavaScript ofrecen una forma eficiente de crear animaciones:
function animateElement() {
const box = document.querySelector('.box');
// Configurar la transición antes de cambiar propiedades
box.style.transition = 'transform 0.5s ease-out, opacity 0.5s ease';
// Aplicar los cambios que activarán la transición
box.style.transform = 'scale(1.2) rotate(5deg)';
box.style.opacity = '0.8';
// Restaurar después de la transición
setTimeout(() => {
box.style.transform = 'scale(1) rotate(0)';
box.style.opacity = '1';
}, 2000);
}
Clases vs. estilos inline: ¿Cuándo usar cada uno?
- Uso de clases CSS (recomendado para la mayoría de casos):
- Para cambios que afectan múltiples propiedades
- Cuando los estilos están predefinidos
- Para mantener la separación de responsabilidades
// Cambiar entre estados visuales predefinidos
function toggleDarkMode() {
document.body.classList.toggle('dark-theme');
// También podemos actualizar elementos hijos
document.querySelectorAll('.card').forEach(card => {
card.classList.toggle('dark-card');
});
// Guardar preferencia del usuario
const isDarkMode = document.body.classList.contains('dark-theme');
localStorage.setItem('darkMode', isDarkMode);
}
- Uso de estilos inline:
- Para valores calculados dinámicamente
- Para animaciones y cambios temporales
- Cuando necesitas precisión absoluta
// Posicionar un tooltip relativo a un elemento
function showTooltip(targetElement, text) {
const tooltip = document.createElement('div');
tooltip.className = 'tooltip';
tooltip.textContent = text;
document.body.appendChild(tooltip);
const rect = targetElement.getBoundingClientRect();
tooltip.style.left = `${rect.left + rect.width / 2 - tooltip.offsetWidth / 2}px`;
tooltip.style.top = `${rect.bottom + 10}px`;
// Mostrar con animación
tooltip.style.opacity = '0';
tooltip.style.transform = 'translateY(-10px)';
tooltip.style.transition = 'all 0.3s ease';
// Forzar reflow para que la transición funcione
tooltip.offsetHeight;
tooltip.style.opacity = '1';
tooltip.style.transform = 'translateY(0)';
}
Variables CSS (propiedades personalizadas)
Las variables CSS combinadas con JavaScript permiten crear temas dinámicos y sistemas de diseño flexibles:
// Cambiar tema de color usando variables CSS
function setThemeColor(primaryColor, secondaryColor) {
document.documentElement.style.setProperty('--primary-color', primaryColor);
document.documentElement.style.setProperty('--secondary-color', secondaryColor);
// Guardar preferencias
localStorage.setItem('theme', JSON.stringify({
primary: primaryColor,
secondary: secondaryColor
}));
}
// Ejemplo de uso
document.querySelector('#theme-selector').addEventListener('change', (e) => {
const theme = e.target.value;
if (theme === 'blue') {
setThemeColor('#3498db', '#2980b9');
} else if (theme === 'green') {
setThemeColor('#2ecc71', '#27ae60');
}
});
Optimización del rendimiento
Al manipular estilos, es importante considerar el rendimiento:
- Minimiza los reflows: Agrupa los cambios de estilo para reducir recálculos de layout
// Mal (causa múltiples reflows)
element.style.width = '100px';
element.style.height = '100px';
element.style.margin = '10px';
// Mejor (un solo reflow)
element.style.cssText = 'width: 100px; height: 100px; margin: 10px;';
// O usando clases (aún mejor)
element.classList.add('box-dimensions');
- Usa
requestAnimationFrame
para animaciones suaves:
function animateProgress(element, targetWidth) {
let width = 0;
function step() {
width += 2;
element.style.width = `${width}%`;
if (width < targetWidth) {
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);
}
// Uso
animateProgress(document.querySelector('.progress-bar'), 75);
Ejemplo práctico: Sistema de notificaciones
Combinando clases y estilos para crear un sistema de notificaciones dinámico:
function showNotification(message, type = 'info') {
const notification = document.createElement('div');
notification.className = 'notification';
notification.classList.add(`notification-${type}`);
notification.textContent = message;
// Añadir al DOM
document.body.appendChild(notification);
// Forzar reflow antes de añadir clase para activar transición
notification.offsetHeight;
// Mostrar con animación
notification.classList.add('notification-visible');
// Configurar auto-cierre
setTimeout(() => {
notification.classList.remove('notification-visible');
// Eliminar del DOM después de la transición
notification.addEventListener('transitionend', () => {
notification.remove();
});
}, 5000);
return notification;
}
Esta combinación de manipulación de clases y estilos permite crear interfaces dinámicas y responsivas que mejoran significativamente la experiencia del usuario, manteniendo un código limpio y fácil de mantener.
Aprendizajes de esta lección de JavaScript
- Dominar el uso de innerText para manipular texto visible.
- Comprender textContent para manejar texto oculto en el DOM.
- Explorar nodeValue para interacciones precisas a nivel de nodo de texto.
- Comparar las diferencias entre innerText, textContent y nodeValue.
- Seleccionar la propiedad adecuada según las necesidades de estilo y rendimiento.
- Aplicar estrategias de seguridad para evitar ataques XSS en manipulación de contenido.
Completa este curso de JavaScript y certifícate
Únete a nuestra plataforma de cursos de programación y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.
Asistente IA
Resuelve dudas al instante
Ejercicios
Practica con proyectos reales
Certificados
Valida tus conocimientos
Más de 25.000 desarrolladores ya se han certificado con CertiDevs