Belirli bir dizeyle başlayan tüm sınıfları kaldır


99

id="a"Birkaç gruptan kendisine eklenmiş herhangi bir sayıda sınıfa sahip olabilen bir div'im var. Her grubun belirli bir öneki vardır. Javascript'te, gruptan hangi sınıfın div üzerinde olduğunu bilmiyorum. Belirli bir öneke sahip tüm sınıfları temizleyebilmek ve ardından yeni bir tane ekleyebilmek istiyorum. "Bg" ile başlayan tüm sınıfları kaldırmak istersem, bunu nasıl yaparım? Bunun gibi bir şey ama aslında işe yarıyor:

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

Yanıtlar:


59

JQuery ile gerçek DOM öğesi sıfır dizinindedir, bu çalışmalıdır

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

34
Buna dikkat et. Kelime sınırı kısa çizgi karakteri ('-') ve noktalar ve diğerlerine bölünür, bu nedenle "bg.a", "bg-a" vb. Gibi sınıf adları kaldırılmayacak, ".a", "-a" vb. İle değiştirilecektir. Dolayısıyla, noktalama karakterleri içeren sınıf adlarınız varsa, sadece basit bir normal ifadeyi değiştirerek sorun yaşayabilirsiniz. İşte SO iplik kelime sınır tanımı hakkında
Jakub P.

6
Kabir Sarin'in aşağıdaki split ('') ve indexOf ile cevabı daha iyi IMO'dur çünkü bu özel karakterli "zombi" sınıflarının ortaya çıkmasına neden olmaz.
Jakub P.

2
Bu yöntem, burada bulunan gibi daha iyi bir normal
ifadeyle

109

Kelime sınırına bölünen bir normal ifade \bbunun için en iyi çözüm değildir:

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

veya jQuery karışımı olarak:

$.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;
};

2018 ES6 Güncellemesi:

const prefix = "prefix";
const classes = el.className.split(" ").filter(c => !c.startsWith(prefix));
el.className = classes.join(" ").trim();

9
Bu, RegExp'i \ b (kelime sınırı kontrolü) ile kullanmaktan daha iyi bir yaklaşımdır çünkü 'zombi sınıflarının' ortaya çıkmasını engeller. Eğer "önek-sonek" gibi sınıflarınız varsa, bu başlıktaki "en iyi cevap" "-suffix" sınıfını terk edecektir çünkü \ b "-" karakterinden önce bölünecektir. Bölünmüş harita birleştirme çözümünüz bunun etrafında çalışır :) Çözümünüzün etrafında küçük bir jQuery eklentisi oluşturdum, Kabir: ( gist.github.com/2881585 )
Jakub S.

3
+1 Ben de aynı fikirdeyim, diğer her yanıt, boşluksuz sözcük sınırlarını aşacak basit bir normal ifade gibi görünüyor. Yarın zamanım olursa, bunu kanıtlayan bir birim testi sağlayacağım.
gerges

1
Bu aslında geçerli bir kod olmasa da, anonim işlevin filterbir boole döndürmesi gerektiğinden , hoşuma gitti . Bu işe yarayacak:var classes = $(e).attr("class").split(" "); $(classes).each(function(i, item) { classes[i] = item.indexOf("prefix") === -1 ? item : "prefix-new"); }); $(e).attr("class", classes.join(" "));
Tim

Daha geçerli bir çözüm şu haritayı kullanır:$e.attr('class', $.map($e.attr('class').split(' '), function (klass) { return klass.indexOf(prefix) != 0 ? klass : undefined; }).join(' '));
M Miller

2
Bu yaklaşım en iyi sonucu verir. @ JakubP'nin eklentisini kullandım. Mümkünse bir öneri: Ne yapar, şimdi sınıfları döndürdüğünde, çok fazla alana neden olur. Örneğin class="blackRow blackText orangeFace blackHead"dönecektir class=" orangeFace "koşarsan removeClassPrefix("black");. Ben şöyle bir sonuç kırparak bu çözüldü: el.className = $.trim(classes.join(" "));.
Albert


11

Bunu halletmek için jQuery'ye özel herhangi bir koda ihtiyacınız yoktur. Bunları değiştirmek için bir RegExp kullanın:

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

Herhangi bir öneki desteklemek için bunu değiştirebilirsiniz, ancak RegExp yalnızca bir kez derleneceğinden daha hızlı yöntem yukarıdadır:

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

9

Kullanımı 2 imza ait $.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>​]

JQuery v1.4'ten beri bu en iyi yaklaşımdır.
Dinei


3

Basit jQuery yapılarını ve dizi işleme işlevlerini kullanarak kullanacağım bir yaklaşım, sınıfın kontrol kimliğini ve önekini alan ve tüm sınıflandırılanları silen bir işlev bildirmektir. Kod eklenmiştir:

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

Artık bu işlev herhangi bir yerden, bir düğmeye tıklayarak veya koddan çağrılabilir:

removeclasses("a","bg");

3

Modern tarayıcılar için:

let element = $('#a')[0];
let cls = 'bg';

element.classList.remove.apply(element.classList, Array.from(element.classList).filter(v=>v.startsWith(cls)));

2

Tam olarak aynı soruna çözüm arıyordum. "Fontid_" önekiyle başlayan tüm sınıfları kaldırmak için Bu makaleyi okuduktan sonra şu anda kullandığım küçük bir eklenti yazdım.

(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));

Kullanım:

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

Bu, 10 kat daha fazla satır ve daha az verimli bir "dizgi ile başlar"
çözümümden

1

Bunun eski bir soru olduğunu biliyorum, ancak yeni bir çözüm buldum ve dezavantajları olup olmadığını bilmek istiyorum.

$('#a')[0].className = $('#a')[0].className
                              .replace(/(^|\s)bg.*?(\s|$)/g, ' ')
                              .replace(/\s\s+/g, ' ')
                              .replace(/(^\s|\s$)/g, '');

1

Tek satırda ... someRegExp bir normal ifadeyle eşleşen tüm sınıfları kaldırır

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

0

Prestaul'un cevabı yardımcı oldu, ancak benim için pek işe yaramadı. İd ile bir nesneyi seçmenin jQuery yolu çalışmadı. Kullanmak zorundaydım

document.getElementById("a").className

onun yerine

$("#a").className

veya $ ("# a") [0] .className as className yalnızca DOM öğesinde kullanılabilir, jQuery nesnesinde kullanılamaz
Naeem Sarfraz

bu bir cevap için bir yorumdur, cevap değil
TJ

0

Ayrıca sınıf adı için tire '-' ve rakamlar kullanıyorum. Yani benim sürümüm '\ d-' içeriyor

$('#a')[0].className = $('#a')[0].className.replace(/\bbg.\d-*?\b/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
Soruyu çok iyi okuduğunu sanmıyorum. Kullanıcı sadece bir sınıfı kaldırıp başka bir sınıf eklemeyi sormuyordu.
Andrew Barber

1
@Andrew Barber: haklısınız bu doğru cevap değil, ancak majorsk8 sadece tek bir sınıfın değil tüm sınıfların nasıl temizleneceğini (removeAttr) önerdi;)
eğin
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.