Hapus semua kelas yang dimulai dengan string tertentu


99

Saya memiliki div id="a"yang mungkin memiliki sejumlah kelas yang menyertainya, dari beberapa grup. Setiap kelompok memiliki prefiks tertentu. Di javascript, saya tidak tahu kelas mana dari grup yang ada di div. Saya ingin menghapus semua kelas dengan prefiks tertentu dan kemudian menambahkan yang baru. Jika saya ingin menghapus semua kelas yang dimulai dengan "bg", bagaimana cara melakukannya? Sesuatu seperti ini, tetapi itu benar-benar berfungsi:

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

Jawaban:


59

Dengan jQuery, elemen DOM sebenarnya berada di indeks nol, ini seharusnya berfungsi

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

34
Hati-hati dengan yang satu ini. Pembagian batas kata pada karakter tanda hubung ('-') dan titik dan lainnya, jadi nama kelas seperti "bg.a", "bg-a" dll. Tidak akan dihapus tetapi diganti dengan ".a", "-a" dll. Jadi, jika Anda memiliki nama kelas dengan karakter tanda baca, Anda mungkin mengalami masalah hanya dengan menjalankan penggantian regex sederhana. Berikut adalah utas SO tentang definisi batas kata
Jakub P.

6
Jawaban Kabir Sarin di bawah ini dengan split ('') dan indexOf adalah IMO yang lebih baik karena tidak akan menyebabkan kelas "zombie" berkarakter khusus itu muncul.
Jakub P.

2
Metode ini masih dapat digunakan dengan regex yang lebih baik, seperti yang ditemukan di sini: stackoverflow.com/a/2644364/1333402
ssmith

109

Pemisahan regex pada batas kata \bbukanlah solusi terbaik untuk ini:

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

atau sebagai 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;
};

Pembaruan ES6 2018:

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

9
Ini adalah pendekatan yang lebih baik daripada menggunakan RegExp dengan \ b (pemeriksaan batas kata) karena mencegah 'kelas zombie' muncul. Jika Anda memiliki kelas seperti "prefix-suffix", 'jawaban terbaik' di utas ini akan meninggalkan kelas '-suffix' karena \ b akan dipisahkan sebelum '-' char. Solusi split-map-join Anda mengatasinya :) Saya membuat plugin jQuery kecil di sekitar solusi Anda, Kabir: ( gist.github.com/2881585 )
Jakub P.

3
+1 Saya juga setuju, setiap jawaban lain tampaknya hanya berupa ekspresi reguler sederhana yang akan melanggar batas kata non-spasi. Jika saya punya waktu besok, saya akan memberikan tes unit yang membuktikan ini.
gerges

1
Saya suka meskipun ini sebenarnya bukan kode yang valid, karena fungsi anonim filterharus mengembalikan boolean. Ini akan berhasil: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

Solusi yang lebih valid menggunakan peta:$e.attr('class', $.map($e.attr('class').split(' '), function (klass) { return klass.indexOf(prefix) != 0 ? klass : undefined; }).join(' '));
M Miller

2
Pendekatan ini bekerja paling baik. Saya menggunakan plugin @ JakubP. Satu saran jika saya boleh: Apa yang dilakukannya, ketika sekarang mengembalikan kelas, itu menyebabkan banyak ruang. Misalnya class="blackRow blackText orangeFace blackHead"akan kembali class=" orangeFace "jika Anda menjalankan removeClassPrefix("black");. Aku memecahkan ini dengan pemangkasan hasil seperti: el.className = $.trim(classes.join(" "));.
Albert

29

Saya telah menulis plugin jQuery sederhana - alterClass , yang melakukan penghapusan kelas wildcard. Secara opsional akan menambahkan kelas juga.

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

Terima kasih Pete! Baru saja menggunakan plugin Anda dan berfungsi dengan baik ... menghemat waktu saya!
jordan.baucke

11

Anda tidak memerlukan kode khusus jQuery untuk menangani ini. Cukup gunakan RegExp untuk menggantinya:

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

Anda dapat memodifikasi ini untuk mendukung awalan apa pun tetapi metode yang lebih cepat ada di atas karena RegExp hanya akan dikompilasi sekali:

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

9

Menggunakan tanda tangan kedua dari $.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>​]

Sejak jQuery v1.4, ini adalah pendekatan terbaik.
Dinei


3

Pendekatan yang akan saya gunakan menggunakan konstruksi jQuery sederhana dan fungsi penanganan array, adalah mendeklarasikan fungsi yang mengambil id dari kontrol dan awalan kelas dan menghapus semua yang diklasifikasikan. Kode terlampir:

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

Sekarang fungsi ini bisa dipanggil dari mana saja, dengan mengklik tombol atau dari kode:

removeclasses("a","bg");

2

Saya sedang mencari solusi untuk masalah yang persis sama. Untuk menghapus semua kelas dimulai dengan awalan "fontid_" Setelah membaca artikel ini saya menulis sebuah plugin kecil yang saya gunakan sekarang.

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

Pemakaian:

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

Ini tidak lebih dari solusi saya dengan 10x lebih banyak baris dan "string dimulai dengan" yang kurang efisien periksa: - /
sarink

2

Untuk browser modern:

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

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

1

Saya tahu ini pertanyaan lama, tetapi saya menemukan solusi baru dan ingin tahu apakah ada kerugiannya?

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

1

Dalam satu baris ... Menghapus semua kelas yang cocok dengan ekspresi reguler someRegExp

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

0

Jawaban Prestaul sangat membantu, tetapi tidak berhasil bagi saya. Cara jQuery untuk memilih objek berdasarkan id tidak berfungsi. Saya harus menggunakan

document.getElementById("a").className

dari pada

$("#a").className

atau $ ("# a") [0] .className sebagai className hanya tersedia pada elemen DOM dan bukan objek jQuery
Naeem Sarfraz

ini adalah komentar untuk jawaban seseorang, bukan jawaban
TJ

0

Saya juga menggunakan tanda hubung'- 'dan angka untuk nama kelas. Jadi versi saya menyertakan '\ d-'

$('#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
Saya rasa Anda tidak membaca pertanyaan dengan baik. Pengguna tidak bertanya tentang menghapus kelas dan menambahkan kelas lain.
Andrew Barber

1
@ Andrew Barber: Anda benar, ini bukan jawaban yang benar, tetapi majorsk8 menyarankan cara menghapus semua kelas (removeAttr), bukan hanya satu kelas;)
Miringkan
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.