jQuery removeClass wildcard


370

มีวิธีง่ายๆในการลบการจับคู่คลาสทั้งหมดหรือไม่ตัวอย่างเช่น

color-*

ดังนั้นถ้าฉันมีองค์ประกอบ:

<div id="hello" class="color-red color-brown foo bar"></div>

หลังจากลบมันจะเป็น

<div id="hello" class="foo bar"></div>

ขอบคุณ!


1
regex เช่นใน "คำตอบที่ยอมรับ" จะแตกบนขอบเขตของคำที่ไม่ใช่ช่องว่าง ฉันโพสต์โซลูชันทางเลือกด้านล่าง ดูเพิ่มเติมได้ที่: stackoverflow.com/questions/57812/…
sarink

@KabirSarin คำตอบที่ยอมรับได้ถูกอัปเดตเพื่อแก้ไขปัญหานี้แล้ว
Emile Bergeron

คำตอบ:


679

removeClassฟังก์ชั่นใช้เวลาโต้แย้งฟังก์ชั่นตั้งแต่jQuery 1.4

$("#hello").removeClass (function (index, className) {
    return (className.match (/(^|\s)color-\S+/g) || []).join(' ');
});

ตัวอย่างสด: http://jsfiddle.net/xa9xS/1409/


4
ฉันคิดว่ามันคุ้มค่าที่จะสังเกตว่าสิ่งนี้จะทำให้เกิดช่องว่างชั้นนำของชั้นเรียนที่ตรงกันซึ่งไม่ได้เริ่มตั้งแต่ต้น Javascript ไม่สนับสนุนการมองในเชิงบวกดังนั้นคุณจะต้องใช้การแก้ไขกลุ่มการดักจับ อย่างไรก็ตามมันเป็นสิ่งที่สงสัยเพราะฟังก์ชั่น removeClass จะตัดช่องว่างจากสตริงคลาสของคุณให้คุณผ่านclasses = ( value || "" ).match( rnotwhite ) || [];
eephillip

ฉันชอบวิธีนี้ดีที่สุด! ฉันจะตรวจสอบว่าจะลบคลาสตั้งแต่สองคลาสขึ้นไปได้อย่างไร เช่นsport-, nav-และcolor-?
lowtechsun

คุณจะทำสิ่งนี้เพื่อให้ตรงกับชั้นเรียนที่ลงท้ายด้วย*-colorอย่างไร?
วงกลม B

3
@lowtechsun คุณสามารถเพิ่มใน regex (color-|sport-|nav-)ของคุณเช่นนี้ มันจะตรงcolor-หรือหรือsport- ดังนั้นคำตอบข้างต้นก็จะกลายเป็นnav- /(^|\s)(color-|sport-|nav-)\S+/g
Bogie

1
คำตอบที่ยอมรับนั้นถูกต้อง แต่โดยปกติแล้วฉันจะใช้ \ b ซึ่งตรงกับขอบเขตของคำใด ๆ มากกว่าที่จะใช้คำมาก (^ | \ s) ตัวอย่างเช่นหากต้องการลบคลาสทั้งหมดที่ประกอบด้วยคำว่าเวทมนต์แล้วตามด้วยจำนวนเต็มที่ไม่เป็นลบและมีเพียงคลาสเหล่านั้นฉันจะจับคู่กับ / \ bmagic \ d + \ b /
CarlEdman

98
$('div').attr('class', function(i, c){
    return c.replace(/(^|\s)color-\S+/g, '');
});

5
ฉันชอบสิ่งนี้เพราะจะช่วยลดค่าใช้จ่ายและตรงประเด็น เหตุใดจึงต้องใช้ remove class เมื่อ attr ทำงานได้ดีกว่า
Angry Dan

2
ฉันคิดว่าคุณต้องป้องกันคลาสที่ว่างเปล่า ( c is undefined)? อย่างน้อยเมื่อฉันลองด้านล่างในปลั๊กอินของฉันในหน้านี้$('a').stripClass('post', 1)โยน "TypeError: ไม่สามารถเรียกวิธีการ 'แทนที่' ของไม่ได้กำหนด"
drzaus

1
@ Kobi ใช่ฉันไม่คิดว่าเป็นไปได้ที่จะกรองคุณลักษณะและส่งคืนผลลัพธ์ที่ไม่มี - $('div[class]')ควรคืนองค์ประกอบด้วยclassไม่ว่าจะมีค่าหรือไม่ก็ตาม สถานการณ์การทดสอบ: jsfiddle.net/drzaus/m83mv
drzaus

1
@Kobi - ฉันคิดว่าฉันเห็นสิ่งที่คุณได้รับ ในกรณีเช่นขอบ.removeProp('class')หรือ.className=undefinedตัวกรองยังคงส่งกลับสิ่งที่พวกเขากำลังเพียง[class] undefinedในทางเทคนิคแล้วมันยังมีคลาส (ซึ่งตรงข้ามกับ.removeAttr('class')ซึ่งเป็นเหตุผลว่าทำไมมันแบ่งฟังก์ชั่นของคุณ แต่ไม่ใช่ตัวแปรของฉัน jsfiddle.net/drzaus/m83mv/4
drzaus

1
การเพิ่มการทดสอบแบบด่วนนั้นเหมาะกับฉัน:return c && c.replace(/\bcolor-\S+/g, '');
ช่างเขียน

50

ฉันได้เขียนปลั๊กอินที่เรียกว่า alterClass - ลบคลาสอิลิเมนต์ด้วยการจับคู่สัญลักษณ์ เพิ่มคลาสแบบเป็นทางเลือก: https://gist.github.com/1517285

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

1
ดีมากจริง ๆ ... ช่วยให้ฉันนำรหัสมาใช้ใหม่ซึ่งฉันต้องการลบTwitter Boostrapคลาสดังนี้:$(".search div").children('div').alterClass('span* row-fluid');
Leniel Maccaferri

15

ฉันได้สรุปสิ่งนี้ลงในปลั๊กอิน Jquery ซึ่งใช้ regex เป็นอาร์กิวเมนต์

กาแฟ:

$.fn.removeClassRegex = (regex) ->
  $(@).removeClass (index, classes) ->
    classes.split(/\s+/).filter (c) ->
      regex.test c
    .join ' '

javascript:

$.fn.removeClassRegex = function(regex) {
  return $(this).removeClass(function(index, classes) {
    return classes.split(/\s+/).filter(function(c) {
      return regex.test(c);
    }).join(' ');
  });
};

ดังนั้นในกรณีนี้การใช้งานจะเป็น (ทั้ง Coffee และ Javascript):

$('#hello').removeClassRegex(/^color-/)

โปรดทราบว่าฉันใช้Array.filterฟังก์ชันที่ไม่มีอยู่ใน IE <9 คุณสามารถใช้ฟังก์ชันตัวกรองของขีดล่างแทนหรือ Google สำหรับโพลีฟิลเช่นWTFPLนี้


11

หากคุณต้องการใช้ในที่อื่นฉันขอแนะนำให้คุณใช้ส่วนขยาย อันนี้ใช้ได้ดีสำหรับฉัน

 $.fn.removeClassStartingWith = function (filter) {
    $(this).removeClass(function (index, className) {
        return (className.match(new RegExp("\\S*" + filter + "\\S*", 'g')) || []).join(' ')
    });
    return this;
};

การใช้งาน:

$(".myClass").removeClassStartingWith('color');

4

เราสามารถรับคลาสทั้งหมดโดย.attr("class")และไปยังอาเรย์และลูปและตัวกรอง:

var classArr = $("#sample").attr("class").split(" ")
$("#sample").attr("class", "")
for(var i = 0; i < classArr.length; i ++) {
    // some condition/filter
    if(classArr[i].substr(0, 5) != "color") {
        $("#sample").addClass(classArr[i]);
    }
}

ตัวอย่าง: http://jsfiddle.net/L2A27/1/


เพิ่มvar prefix='color';และเปลี่ยนแปลง ...if (classArr[i].substr(0, prefix.length) != prefix)
Rich C

4

คล้ายกับคำตอบของ @ tremby นี่คือคำตอบของ @ Kobi ในฐานะปลั๊กอินที่จะตรงกับคำนำหน้าหรือคำต่อท้าย

  • อดีต) แถบbtn-miniและbtn-dangerแต่ไม่เมื่อbtnstripClass("btn-")
  • อดีต) แถบhorsebtnและcowbtnแต่ไม่btn-miniหรือbtnเมื่อstripClass('btn', 1)

รหัส:

$.fn.stripClass = function (partialMatch, endOrBegin) {
    /// <summary>
    /// The way removeClass should have been implemented -- accepts a partialMatch (like "btn-") to search on and remove
    /// </summary>
    /// <param name="partialMatch">the class partial to match against, like "btn-" to match "btn-danger btn-active" but not "btn"</param>
    /// <param name="endOrBegin">omit for beginning match; provide a 'truthy' value to only find classes ending with match</param>
    /// <returns type=""></returns>
    var x = new RegExp((!endOrBegin ? "\\b" : "\\S+") + partialMatch + "\\S*", 'g');

    // https://stackoverflow.com/a/2644364/1037948
    this.attr('class', function (i, c) {
        if (!c) return; // protect against no class
        return c.replace(x, '');
    });
    return this;
};

https://gist.github.com/zaus/6734731


1
สำหรับบันทึกฉันไม่เห็นด้วยที่จะง่ายกว่านี้
tremby

@tremby ขอโทษฉันหมายง่ายในแบบฉบับการใช้งาน (เช่นคำนำหน้าและคำต่อท้าย) เนื่องจากคุณไม่ต้องเขียน regex แต่ละครั้ง
drzaus

3
ฉันยังไม่เห็นด้วย ด้วยวิธีการของคุณคุณจะต้องอ่านเอกสารประกอบและจำค่าที่endOrBeginต้องใช้ มันไม่ได้อธิบายตนเอง การเขียน regex ยากอะไร /^match-at-start/และ/match-at-end$/เป็นที่รู้จักของนักพัฒนา JS ทุกคน แต่แต่ละคนก็เพื่อตัวเขาเอง
tremby

1
@tremby อื่น ๆ กว่า regexes ขอทานที่จะทำร้ายตัวเลือกที่ไม่ใช่ regex ใกล้ชิดมากขึ้นตรงกับลายเซ็นที่มีอยู่ของaddClass, removeClassและtoggleClassซึ่งเป็นที่รู้จักกันพัฒนาทุก jQuery การอ่านเอกสารคู่มือยากแค่ไหน? ;)
drzaus

2
ไม่มีอะไรยากเกี่ยวกับการอ่านเอกสาร แต่อย่างที่ @tremby พูดว่าวิธีแก้ปัญหาของเขานั้นอธิบายได้ด้วยตนเองในขณะที่คุณต้องการเอกสารประกอบ โซลูชันแบบอธิบายตนเองนั้นใช้งานง่ายขึ้นตามนิยาม
Francisco Hodge

2

สำหรับปลั๊กอิน jQuery ลองนี้

$.fn.removeClassLike = function(name) {
    return this.removeClass(function(index, css) {
        return (css.match(new RegExp('\\b(' + name + '\\S*)\\b', 'g')) || []).join(' ');
    });
};

หรือสิ่งนี้

$.fn.removeClassLike = function(name) {
    var classes = this.attr('class');
    if (classes) {
        classes = classes.replace(new RegExp('\\b' + name + '\\S*\\s?', 'g'), '').trim();
        classes ? this.attr('class', classes) : this.removeAttr('class');
    }
    return this;
};

2

จากคำตอบของARS81 (ตรงกับชื่อคลาสที่ขึ้นต้นด้วย) นี่คือเวอร์ชันที่ยืดหยุ่นกว่า ยังhasClass()รุ่น regex

การใช้งาน: $('.selector').removeClassRegex('\\S*-foo[0-9]+')

$.fn.removeClassRegex = function(name) {
  return this.removeClass(function(index, css) {
    return (css.match(new RegExp('\\b(' + name + ')\\b', 'g')) || []).join(' ');
  });
};

$.fn.hasClassRegex = function(name) {
  return this.attr('class').match(new RegExp('\\b(' + name + ')\\b', 'g')) !== null;
};

2

สิ่งนี้จะลบชื่อคลาสทั้งหมดที่ขึ้นต้นด้วยprefixจากclassแอ็ตทริบิวต์ของโหนดอย่างมีประสิทธิภาพ คำตอบอื่น ๆ ไม่สนับสนุนองค์ประกอบSVG (ขณะที่เขียนนี้) แต่วิธีการแก้ปัญหานี้ไม่:

$.fn.removeClassPrefix = function(prefix){
    var c, regex = new RegExp("(^|\\s)" + prefix + "\\S+", 'g');
    return this.each(function(){
        c = this.getAttribute('class');
        this.setAttribute('class', c.replace(regex, ''));
    });
};

มันจะมีประสิทธิภาพมากกว่าในการสร้างRegExpวัตถุหนึ่งครั้งจากการติดต่อกลับแต่ละครั้งหรือไม่
Emile Bergeron

1
@EmileBergeron - ใช่มันจะเป็น! ฉันจะทำการเปลี่ยนแปลง
vsync

2

ฉันมีปัญหาเดียวกันและเกิดขึ้นกับสิ่งต่อไปนี้ที่ใช้เมธอด _.filter ของขีดล่าง เมื่อฉันค้นพบว่า removeClass รับฟังก์ชั่นและให้รายชื่อคลาสคุณก็สามารถเปลี่ยนให้เป็นอาร์เรย์และกรอง classname เพื่อกลับไปยังเมธอด removeClass

// Wildcard removeClass on 'color-*'
$('[class^="color-"]').removeClass (function (index, classes) {
  var
    classesArray = classes.split(' '),
    removeClass = _.filter(classesArray, function(className){ return className.indexOf('color-') === 0; }).toString();

  return removeClass;
});

1
คุณช่วยอธิบายสิ่งที่ขีดเส้นใต้ทำใน _.filter
bart

2

นอกจากนี้คุณยังสามารถทำเช่นนี้กับวานิลลา JavaScript ใช้Element.classList ไม่จำเป็นต้องใช้นิพจน์ทั่วไปเช่นกัน:

function removeColorClasses(element) { for (let className of Array.from(element.classList)) if (className.startsWith("color-")) element.classList.remove(className); }

หมายเหตุ: โปรดสังเกตว่าเราสร้างArrayสำเนาของclassListก่อนเริ่มต้นสิ่งสำคัญเนื่องจากclassListเป็นรายการสดDomTokenListซึ่งจะอัปเดตเมื่อมีการลบคลาสออก


1

คุณสามารถใช้classNameคุณสมบัติของวัตถุ DOM ขององค์ประกอบ:

var $hello = $('#hello');
$('#hello').attr('class', $hello.get(0).className.replace(/\bcolor-\S+/g, ''));

1

ฟังก์ชันทั่วไปที่ลบคลาสใด ๆ ที่ขึ้นต้นด้วยbegin:

function removeClassStartingWith(node, begin) {
    node.removeClass (function (index, className) {
        return (className.match ( new RegExp("\\b"+begin+"\\S+", "g") ) || []).join(' ');
    });
}

http://jsfiddle.net/xa9xS/2900/

var begin = 'color-';

function removeClassStartingWith(node, begin) {
    node.removeClass (function (index, className) {
        return (className.match ( new RegExp("\\b"+begin+"\\S+", "g") ) || []).join(' ');
    });
}

removeClassStartingWith($('#hello'), 'color-');

console.log($("#hello")[0].className);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="hello" class="color-red color-brown foo bar"></div>


0

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

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

หรือเป็น mixQuery 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 = classes.join(" ");
    });
    return this;
};

0

หากคุณมีองค์ประกอบมากกว่าหนึ่งรายการที่มีชื่อคลาส 'ตัวอย่าง' เพื่อลบคลาสของ 'color-' ในรายการทั้งหมดคุณสามารถทำได้ดังนี้: [using jquery]

var objs = $('html').find('.example');
for(index=0 ; index < obj1s.length ; index++){
    objs[index].className = objs[index].className.replace(/col-[a-z1-9\-]*/,'');
}

ถ้าคุณไม่ใส่ [a-z1-9 -] * ใน regex ของคุณมันจะไม่ลบคลาสที่มีตัวเลขหรือ '-' อยู่ในชื่อของมัน


0

หากคุณเพียงแค่ต้องลบสีชุดสุดท้ายดังต่อไปนี้อาจเหมาะกับคุณ

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

รหัส:

var colorID = 'Whatever your new color is';

var bodyTag = $('body');
var prevColor = bodyTag.data('currentColor'); // get current color
bodyTag.removeClass(prevColor);
bodyTag.addClass(colorID);
bodyTag.data('currentColor',colorID); // set the new color as current

อาจไม่ใช่สิ่งที่คุณต้องการ แต่สำหรับฉันมันเป็นและนี่คือคำถาม SO แรกที่ฉันดูดังนั้นคิดว่าฉันจะแบ่งปันโซลูชันของฉันในกรณีที่มันช่วยใครได้


นี่ไม่เกี่ยวข้องเลย คุณอาจตอบคำถามของคุณเองเนื่องจากเป็นพฤติกรรมที่ได้รับการสนับสนุนบน SO
Emile Bergeron

@Emile: จริง ฉันอาจทำเช่นนั้นเนื่องจากไม่ได้ตอบคำถามเดิมโดยตรง ฉันควรทิ้งคำตอบนี้ไว้หรือเอาออก?
redfox05

ณ จุดนี้มันเป็นความเสี่ยงของคุณเองยังไม่ได้ลงคะแนนหรือ upvoted ยัง ดังนั้นคุณสามารถย้ายคำถามของคุณเองโดยไม่มีความเสี่ยง นอกจากนี้พยายามหลีกเลี่ยงการซ้ำซ้อนโดยตรวจสอบว่ามีคำถามเกี่ยวกับเรื่องนี้อยู่แล้ว
Emile Bergeron

0

อีกทางเลือกหนึ่งในการเข้าถึงปัญหานี้คือการใช้คุณลักษณะข้อมูลซึ่งเป็นลักษณะเฉพาะ

คุณต้องการกำหนดสีขององค์ประกอบเช่น: $el.attr('data-color', 'red');

และคุณต้องการสไตล์ใน css เช่น: [data-color="red"]{ color: tomato; }

สิ่งนี้ขัดแย้งกับความจำเป็นในการใช้คลาสซึ่งมีผลข้างเคียงของการต้องการลบคลาสเก่า

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.