ลบคลาสทั้งหมดที่ขึ้นต้นด้วยสตริงที่กำหนด


99

ฉันมี div id="a"ซึ่งอาจมีจำนวนคลาสที่แนบมาจากหลายกลุ่ม แต่ละกลุ่มมีคำนำหน้าเฉพาะ ในจาวาสคริปต์ฉันไม่รู้ว่าคลาสจากกลุ่มไหนอยู่บน div ฉันต้องการล้างชั้นเรียนทั้งหมดด้วยคำนำหน้าที่กำหนดแล้วเพิ่มใหม่ ถ้าฉันต้องการลบคลาสทั้งหมดที่ขึ้นต้นด้วย "bg" ฉันจะทำอย่างไร อะไรทำนองนี้ แต่ใช้งานได้จริง:

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

คำตอบ:


59

ด้วย jQuery องค์ประกอบ DOM จริงจะอยู่ที่ศูนย์ดัชนีสิ่งนี้ควรใช้งานได้

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

34
ระมัดระวังกับสิ่งนี้ การแบ่งขอบเขตของคำบนอักขระเส้นประ ('-') และจุดและอื่น ๆ ดังนั้นชื่อคลาสเช่น "bg.a", "bg-a" ฯลฯ จะไม่ถูกลบออก แต่แทนที่ด้วย ".a", "-a" เป็นต้น ดังนั้นหากคุณมีชื่อชั้นเรียนที่มีอักขระเครื่องหมายวรรคตอนคุณอาจประสบปัญหาเพียงแค่เรียกใช้ regex ง่ายๆ นี่คือเธรด SO เกี่ยวกับนิยามขอบเขตของคำ
Jakub P.

6
คำตอบของ Kabir Sarin ด้านล่างโดยแยก ('') และ indexOf เป็น IMO ที่ดีกว่าเพราะจะไม่ทำให้คลาส "ซอมบี้" ที่มีลักษณะพิเศษเหล่านั้นปรากฏขึ้น
Jakub P.

2
วิธีนี้ยังสามารถใช้กับ regex ที่ดีกว่าได้เช่นที่นี่: stackoverflow.com/a/2644364/1333402
ssmith

109

regex การแบ่งขอบเขตของคำ\bไม่ใช่ทางออกที่ดีที่สุดสำหรับสิ่งนี้:

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

หรือเป็น jQuery mixin:

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

อัปเดต ES6 2018:

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

9
นี่เป็นแนวทางที่ดีกว่าการใช้ RegExp กับ \ b (การตรวจสอบขอบเขตคำ) เพราะป้องกันไม่ให้ 'คลาสซอมบี้' โผล่ขึ้นมา หากคุณมีคลาสเช่น "คำนำหน้า - คำต่อท้าย" "คำตอบที่ดีที่สุด" ในชุดข้อความนี้จะออกจากคลาส "-suffix" เนื่องจาก \ b จะแยกก่อนอักขระ "-" โซลูชันการรวมแผนที่แยกของคุณใช้งานได้ดี :) ฉันสร้างปลั๊กอิน jQuery เล็ก ๆ รอบ ๆ โซลูชันของคุณ Kabir: ( gist.github.com/2881585 )
Jakub P.

3
+1 ฉันเห็นด้วยเช่นกันทุกคำตอบดูเหมือนจะเป็นนิพจน์ทั่วไปที่จะทำลายขอบเขตของคำที่ไม่ใช่ช่องว่าง ถ้าฉันมีเวลาพรุ่งนี้ฉันจะจัดให้มีการทดสอบหน่วยที่พิสูจน์สิ่งนี้
Gerges

1
ฉันชอบแม้ว่านี่จะไม่ใช่รหัสที่ถูกต้องเนื่องจากฟังก์ชันที่ไม่ระบุชื่อในfilterต้องส่งคืนบูลีน สิ่งนี้จะได้ผล: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

วิธีแก้ปัญหาที่ถูกต้องมากขึ้นใช้แผนที่:$e.attr('class', $.map($e.attr('class').split(' '), function (klass) { return klass.indexOf(prefix) != 0 ? klass : undefined; }).join(' '));
M Miller

2
แนวทางนี้ได้ผลดีที่สุด ฉันใช้ปลั๊กอินของ @ JakubP คำแนะนำอย่างหนึ่งถ้าฉันทำได้: มันทำอะไรได้บ้างเมื่อส่งคืนคลาสในตอนนี้มันทำให้เกิดช่องว่างมาก ตัวอย่างเช่นclass="blackRow blackText orangeFace blackHead"จะกลับมาถ้าคุณทำงานclass=" orangeFace " ฉันจะแก้ไขนี้โดยการตัดแต่งผลเช่นดังนั้น:removeClassPrefix("black"); el.className = $.trim(classes.join(" "));
Albert

29

ฉันได้เขียนปลั๊กอิน jQueryง่ายๆ- alterClassซึ่งจะลบคลาสสัญลักษณ์ตัวแทน สามารถเลือกเพิ่มชั้นเรียนได้ด้วย

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

ขอบคุณพีท! เพิ่งใช้ปลั๊กอินของคุณและใช้งานได้ดี ... ช่วยฉันได้บ้าง!
jordan.baucke

11

คุณไม่จำเป็นต้องมีรหัสเฉพาะ jQuery เพื่อจัดการสิ่งนี้ เพียงใช้ RegExp เพื่อแทนที่:

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

คุณสามารถแก้ไขสิ่งนี้เพื่อรองรับคำนำหน้าใด ๆ แต่วิธีที่เร็วกว่านั้นอยู่ข้างบนเนื่องจาก RegExp จะถูกคอมไพล์เพียงครั้งเดียว:

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

9

ใช้ลายเซ็นที่ 2ของ$.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 นี่เป็นแนวทางที่ดีที่สุด
Dinei

3

http://www.mail-archive.com/jquery-en@googlegroups.com/msg03998.htmlพูดว่า:

... และ. removeClass () จะลบคลาสทั้งหมด ...

มันได้ผลสำหรับฉัน;)

ไชโย


นี่คือทางเลือกที่ดีกว่า! ผลงาน
Afshin Mehrabani

12
คำถามไม่ได้ถามถึงวิธีลบคลาสทั้งหมด แต่จะถามวิธีลบคลาสทั้งหมดที่ขึ้นต้นด้วยสตริง สองสิ่งนี้แตกต่างกันมาก
Chris Harrison

3

วิธีการที่ฉันจะใช้โดยใช้โครงสร้าง jQuery แบบง่ายและฟังก์ชันการจัดการอาร์เรย์คือการประกาศฟังก์ชันที่ใช้ id ของการควบคุมและคำนำหน้าของคลาสและลบคลาสทั้งหมด แนบรหัส:

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

ตอนนี้สามารถเรียกใช้ฟังก์ชันนี้ได้จากทุกที่ไม่ว่าจะคลิกปุ่มหรือจากรหัส:

removeclasses("a","bg");

3

สำหรับเบราว์เซอร์สมัยใหม่:

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

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

2

ฉันกำลังมองหาวิธีแก้ปัญหาเดียวกัน ในการลบคลาสทั้งหมดที่ขึ้นต้นด้วยคำนำหน้า "fontid_" หลังจากอ่านบทความนี้ฉันได้เขียนปลั๊กอินขนาดเล็กที่ฉันใช้อยู่ตอนนี้

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

การใช้งาน:

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

นี่ไม่ใช่วิธีแก้ปัญหาของฉันที่มีเส้นเพิ่มขึ้น 10 เท่าและ "สตริงเริ่มต้นด้วย" ที่มีประสิทธิภาพน้อยกว่า: - /
sarink

1

ฉันรู้ว่ามันเป็นคำถามเก่า แต่ฉันพบวิธีแก้ปัญหาใหม่และอยากรู้ว่ามันมีข้อเสียหรือไม่?

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

ในปี 2020 ข้อเสียคือ jQuery
connexo

1

ในบรรทัดเดียว ... ลบคลาสทั้งหมดที่ตรงกับนิพจน์ทั่วไปsomeRegExp

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

0

คำตอบของ Prestaul มีประโยชน์ แต่ก็ไม่ได้ผลสำหรับฉัน วิธี jQuery ในการเลือกวัตถุตาม id ไม่ทำงาน ฉันต้องใช้

document.getElementById("a").className

แทน

$("#a").className

หรือ $ ("# a") [0] .className เป็น className ใช้ได้เฉพาะในองค์ประกอบ DOM ไม่ใช่วัตถุ jQuery
Naeem Sarfraz

นี่คือความคิดเห็นของใครบางคนคำตอบไม่ใช่คำตอบ
TJ

0

ฉันยังใช้ยัติภังค์และตัวเลขสำหรับชื่อคลาส ดังนั้นเวอร์ชันของฉันจึงมี "\ 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
ฉันไม่คิดว่าคุณอ่านคำถามได้ดีขนาดนี้ ผู้ใช้ไม่ได้ถามเกี่ยวกับการลบคลาสและเพิ่มอีกคลาส
Andrew Barber

1
@Andrew Barber: คุณพูดถูกนี่ไม่ใช่คำตอบที่ถูกต้อง แต่ majorsk8 แนะนำวิธีการล้างคลาสทั้งหมด (removeAttr) ไม่ใช่แค่ชั้นเดียว;)
เอียง
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.