Quiero agregar una clase de estilo CSS a todas las instancias de un conjunto selectivo de elementos: por ejemplo, todos los elementos p y todos los elementos h4 .
Defino dos variables JS que obtienen todos los elementos de las etiquetas antes mencionadas y las inserto en una matriz, para poder crear una función que, en teoría, debería aplicar la clase seleccionada a todas las instancias de los elementos/etiquetas seleccionados.
Sin embargo, cuando ejecuto el código, parece que la función asigna la clase solo al primer elemento de la matriz.
<html> <head> <meta charset="utf-8"> <title>JS Bin</title> <style> .italic { font-style: italic; } </style> </head> <body> <h4>Text goes in here</h4> <p>Text goes in here</p> <script> function styleTxt() { let h4Elems = document.getElementsByTagName("H4"); let pElems = document.getElementsByTagName("P"); const elemArray = [pElems, h4Elems]; for (eachElem in elemArray) { let elemInsts = elemArray[eachElem]; for (eachInst in elemInsts) { let givenInst = elemInsts[eachInst]; givenInst.classList.add("italic"); } } } styleTxt(); </script> </body> </html>Si invierto el orden de las etiquetas de elementos dentro de la matriz, entonces el elemento h4 obtendrá la clase .cursiva pero el elemento p no.
¿Quizás no es posible usar la directiva "documento" dos veces? ¿Existe un método alternativo para agregar automáticamente la misma clase a un conjunto de etiquetas html múltiples (pero no todas)?
Está recorriendo cada propiedad de HTMLCollection, incluidas propiedades como length , lo que hace que givenInst sea un número. Dado que no tiene la propiedad classList , llamar a add on undefined crea un error y finaliza el ciclo.
Para resolver esto, puede usar isNaN para verificar si la propiedad es un número o no:
.italic { font-style: italics; } <html> <head> <meta charset="utf-8"> <title>JS Bin</title> <style> .italic { font-style: italic; } </style> </head> <body> <h4>Text goes in here</h4> <p>Text goes in here</p> <script> function styleTxt() { let h4Elems = document.getElementsByTagName("H4"); let pElems = document.getElementsByTagName("P"); const elemArray = [pElems, h4Elems]; for (eachElem in elemArray) { let elemInsts = elemArray[eachElem]; for (eachInst in elemInsts) { if (!isNaN(eachInst)) { let givenInst = elemInsts[eachInst]; givenInst.classList.add("italic"); } } } } styleTxt(); </script> </body> </html> Sin embargo, una mejor manera es usar un bucle for...of en su lugar:
.italic { font-style: italics; } <html> <head> <meta charset="utf-8"> <title>JS Bin</title> <style> .italic { font-style: italic; } </style> </head> <body> <h4>Text goes in here</h4> <p>Text goes in here</p> <script> function styleTxt() { let h4Elems = document.getElementsByTagName("H4"); let pElems = document.getElementsByTagName("P"); const elemArray = [pElems, h4Elems]; for (eachElem of elemArray) { for (eachInst of eachElem) { eachInst.classList.add("italic"); } } } styleTxt(); </script> </body> </html>Es posible que desee preferir el bucle for ...of para esto y hacer uso del operador de propagación . Producirá una salida de código mucho mejor:
function styleTxt() { const h4Elems = document.getElementsByTagName("H4"); const pElems = document.getElementsByTagName("P"); const elemArray = [...pElems, ...h4Elems]; for (const eachElem of elemArray) { eachElem.classList.add("italic"); } } Por supuesto, siempre puede elegir ambos tipos de elementos de una sola vez con el método querySelectorAll :
const all = document.querySelectorAll("h4, p"); // Using the for...of loop: for ( const el of all ){ el.classList.add("italic"); } // Using the `forEach` method: all.forEach( el => el.classList.add("italic") )Use Document.querySelectorAll() para obtener ambos tipos de elementos. NodeList con NodeList.forEach() y agregue la clase a cada elemento.
function styleTxt() { document.querySelectorAll('h4, p') .forEach(el => el.classList.add('italic')); } styleTxt(); .italic { font-style: italic; } <h4>Text goes in here</h4> <p>Text goes in here</p>