2008-09-11 40 views
96

Tengo un div con id="a" que puede tener cualquier cantidad de clases asociadas, de varios grupos. Cada grupo tiene un prefijo específico. En el javascript, no sé qué clase del grupo está en el div. Quiero poder borrar todas las clases con un prefijo dado y luego agregar una nueva. Si quiero eliminar todas las clases que comienzan con "bg", ¿cómo hago eso? Algo como esto, pero que realmente funciona:Eliminar todas las clases que comienzan con una cierta cadena

$("#a").removeClass("bg*"); 

Respuesta

56

con jQuery, el elemento DOM real está en el índice cero, esto debería funcionar

$('#a')[0].className = $('#a')[0].className.replace(/\bbg.*?\b/g, ''); 
+31

Cuidado con este. El límite de palabras se divide en el carácter del tablero ('-') y puntos y otros, por lo que los nombres de clase como "bg.a", "bg-a" etc. no se eliminarán, sino que se reemplazarán por ".a", "-a", etc. Así que si tiene nombres de clase con caracteres de puntuación, puede tener problemas simplemente ejecutando una simple sustitución de expresiones regulares. Aquí hay un hilo SO [sobre la definición de límite de palabras] (http://stackoverflow.com/questions/1324676/what-is-a-word-boundary-in-regexes) –

+5

La respuesta de Kabir Sarin a continuación con split ('') y indexOf es mejor IMO porque no provocará la aparición de esas clases de "zombies" especiales. –

+2

Este método todavía se puede usar con una mejor expresión regular, como la que se encuentra aquí: http://stackoverflow.com/a/2644364/1333402 – ssmith

10

No necesita ningún código específico de jQuery para manejar esto. Sólo tiene que utilizar una expresión regular para reemplazarlos:

$("#a").className = $("#a").className.replace(/\bbg.*?\b/g, ''); 

Usted puede modificar esto para apoyar cualquier prefijo, pero el método más rápido está por encima de como la expresión regular será compilado una sola vez: Respuesta

function removeClassByPrefix(el, prefix) { 
    var regx = new RegExp('\\b' + prefix + '.*?\\b', 'g'); 
    el.className = el.className.replace(regx, ''); 
    return el; 
} 
0

de Prestaul era útil, pero no funcionó para mí. La forma jQuery de seleccionar un objeto por id no funcionó. Tuve que usar

document.getElementById("a").className 

en lugar de

$("#a").className 
+0

En jQuery, esto funcionaría:. $ ("# a") Get (0) .className – georgebrock

+0

o $ ("#a") [0] .className como className solo está disponible en el elemento DOM y no en el objeto jQuery –

+0

este es un comentario para la respuesta de alguien, no una respuesta –

0

También uso hyphen'-' y dígitos para el nombre de la clase. Así que mi versión incluye '\ d-'

$('#a')[0].className = $('#a')[0].className.replace(/\bbg.\d-*?\b/g, ''); 
29

He escrito un simple plugin de jQuery, alterClass, que hace la extracción de clase comodín. añadiremos opcionalmente también clases: https://gist.github.com/1517285

$('#foo').alterClass('foo-* bar-*', 'foobar') 
+0

Gracias Pete! Solo usé tu complemento y funciona genial ... ¡me salvó un poco de tiempo! –

+0

muy agradable, gracias. – prdatur

+0

Cool @ pete-b muchas gracias;) time saver –

101

Una división de expresiones regulares en el límite de la palabra \b no es la mejor solución para esto:

var prefix = "prefix"; 
var classes = el.className.split(" ").filter(function(c) { 
    return c.lastIndexOf(prefix, 0) !== 0; 
}); 
el.className = classes.join(" ").trim(); 

o como un mixin jQuery:

$.fn.removeClassPrefix = function(prefix) { 
    this.each(function(i, el) { 
     var classes = el.className.split(" ").filter(function(c) { 
      return c.lastIndexOf(prefix, 0) !== 0; 
     }); 
     el.className = $.trim(classes.join(" ")); 
    }); 
    return this; 
}; 
+9

Este es un mejor enfoque que el uso de RegExp con \ b (control de límite de palabras) porque evita que aparezcan 'clases de zombies'. Si tiene clases como "prefijo-sufijo", la "mejor respuesta" en este hilo dejará la clase '-suffix' porque \ b se dividirá antes de '-' char. Su solución split-map-join funciona alrededor de eso :) Creé un pequeño plugin jQuery alrededor de su solución, Kabir: (https://gist.github.com/2881585) –

+3

+1 Yo también estoy de acuerdo, todas las demás respuestas parece ser simplemente una expresión regular que se rompería en los límites de las palabras no espaciales. Si tengo tiempo mañana, proporcionaré una prueba unitaria que así lo demuestre. – gerges

+2

Prefiero este método: http://stackoverflow.com/a/2644364/560287 –

1

Sé que es una vieja pregunta, pero encontré una nueva solución y quiero saber si tiene desventajas?

$('#a')[0].className = $('#a')[0].className 
           .replace(/(^|\s)bg.*?(\s|$)/g, ' ') 
           .replace(/\s\s+/g, ' ') 
           .replace(/(^\s|\s$)/g, ''); 
0
(function($) 
{ 
    return this.each(function() 
    { 
     var classes = $(this).attr('class'); 

     if(!classes || !regex) return false; 

     var classArray = []; 

     classes = classes.split(' '); 

     for(var i=0, len=classes.length; i<len; i++) if(!classes[i].match(regex)) classArray.push(classes[i]); 

     $(this).attr('class', classArray.join(' ')); 
    }); 
})(jQuery); 
-6
$("#element").removeAttr("class").addClass("yourClass"); 
+3

No creo que hayas leído la pregunta muy bien. El usuario no estaba preguntando acerca de simplemente eliminar una clase y agregar otra. –

+1

@ Andrew Barber: tienes razón, esta no es la respuesta correcta, pero majorsk8 sugirió cómo borrar todas las clases (removeAttr), no solo una sola;) – Tilt

9

Usando 2nd signature de $.fn.removeClass:

// Considering: 
var $el = $('<div class=" foo-1 a b foo-2 c foo"/>'); 

function makeRemoveClassHandler(regex) { 
    return function (index, classes) { 
    return classes.split(/\s+/).filter(function (el) {return regex.test(el);}).join(' '); 
    } 
} 

$el.removeClass(makeRemoveClassHandler(/^foo-/)); 
//> [<div class=​"a b c foo">​</div>​] 
+0

Desde jQuery v1.4, este es el mejor enfoque. – Dinei

2

que estaba buscando solución para exactamente el mismo problema.Para eliminar todas las clases comenzando con el prefijo "fontid_" Después de leer este artículo escribí un pequeño complemento que estoy usando ahora.

(function ($) { 
     $.fn.removePrefixedClasses = function (prefix) { 
      var classNames = $(this).attr('class').split(' '), 
       className, 
       newClassNames = [], 
       i; 
      //loop class names 
      for(i = 0; i < classNames.length; i++) { 
       className = classNames[i]; 
       // if prefix not found at the beggining of class name 
       if(className.indexOf(prefix) !== 0) { 
        newClassNames.push(className); 
        continue; 
       } 
      } 
      // write new list excluding filtered classNames 
      $(this).attr('class', newClassNames.join(' ')); 
     }; 
    }(fQuery)); 

Uso:

$('#elementId').removePrefixedClasses('prefix-of-classes_'); 
+0

Esto no es más que mi solución con 10x más líneas y una comprobación menos eficiente de "string starts with": - / – sarink

2

Un enfoque me gustaría utilizar usando construcciones simples jQuery y funciones de manipulación de matriz, es declarar una función que toma id del control y el prefijo de la clase y eliminado todos clasificado . El código se adjunta:

function removeclasses(controlIndex,classPrefix){ 
    var classes = $("#"+controlIndex).attr("class").split(" "); 
    $.each(classes,function(index) { 
     if(classes[index].indexOf(classPrefix)==0) { 
      $("#"+controlIndex).removeClass(classes[index]); 
     } 
    }); 
} 

Ahora bien, esta función puede ser llamada desde cualquier lugar, onclick del botón o del código:

removeclasses("a","bg"); 
0

En una línea ... Elimina todas las clases que coincidan con una expresión regular someRegExp

$('#my_element_id').removeClass(function() { return (this.className.match(/someRegExp/g) || []).join(' ').replace(prog.status.toLowerCase(),'');}); 
Cuestiones relacionadas