Estoy estudiando el código en https://youmightnotneedjquery.com/#remove_class :
if (el.classList) el.classList.remove(className); else el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');Me pregunto por qué se molesta en usar RegExp para realizar el reemplazo. ¿Por qué no usar una versión más simple, como la siguiente?
if (el.classList) el.classList.remove(className); else el.className = el.className.replace(className, ' ');Actualización Creo que la primera versión tiene un error. El nombre de la clase HTML distingue entre mayúsculas y minúsculas, consulte ¿Los nombres de clase en los selectores de CSS distinguen entre mayúsculas y minúsculas? , por lo que la bandera 'i' no debe usarse en RegExp.
Porque podría tener una clase que contenga la clase especificada como una subcadena.
Suponga que tiene un elemento con class="abc1 abc" y desea eliminar abc . Su código reemplazará el primer abc , por lo que cambiará a class="1 abc" en lugar de class="abc1" .
No parece un buen enfoque, ni en general ni en ese ejemplo en particular.
Esa expresión regular parece tener la intención de permitir que se pasen cadenas que son una lista de nombres de clase separados por espacios, en lugar de cadenas separadas como lo haría con HTMLElement.classList.remove() . Si intenta pasar una cadena que contiene un espacio a HTMLElement.classList.remove() , generará una DOMException .
No creo que el enfoque de expresión regular que encontró en ese sitio web funcione como debería. Echemos un vistazo a un par de cadenas de entrada de ejemplo y las expresiones regulares resultantes:
string: 'class-a' regex: /(^|\b)class-a(\b|$)/giEsta expresión regular es bastante clara, primero busca el comienzo de la cadena o un salto de palabra, luego la cadena "clase-a", luego un salto de palabra o el final de la cadena.
Debido a que la línea de código contiene className.split(' ') , parece que está diseñado para manejar cadenas que contienen caracteres de espacio. Como esto:
string: 'class-a class-b' regex: /(^|\b)class-a|class-b(\b|$)/gi Sin embargo, debido a que no envuelve la sección de nombre de clase de la expresión regular entre paréntesis para crear su propio grupo, termina siendo lo anterior. Esa expresión regular se divide por la mitad por ese | carácter, y busca dos cosas que coincidan:
Eso significa que coincidiría con las clases que no debería para una classList como class-a2 thisclass-b .
Hay otro par de problemas también. Las clases de CSS distinguen entre mayúsculas y minúsculas, por lo que no tiene sentido utilizar una expresión regular que no distinga entre mayúsculas y minúsculas. Además, la expresión regular intenta usar \b para detectar el principio o el final de un nombre de clase CSS, pero \b también coincidirá con los límites entre letras y guiones, por lo que la cadena 'class-a-1' coincidirá con la expresión regular. /(^|\b)class-a(\b|$)/ .
En cambio, sería mejor convertir la cadena classList de su elemento en una matriz de clases individuales usando split(' ') , luego encontrar su clase en esa matriz de cadenas y eliminarla usando algo como Array.prototype.splice , luego vuelva a unirse a la matriz de nuevo en una cadena classList y sobrescriba la anterior. Algo como esto:
if (el.classList) { el.classList.remove(className); } else { let classes = el.className.split(' '); let classIndex = classes.indexOf(className); if (classIndex !== -1) { classes.splice(classIndex, 1); } el.className = classes.join(' '); }