Видаліть усі класи, які починаються певним рядком


99

У мене є div, з id="a"яким може бути додано будь-яку кількість класів із декількох груп. Кожна група має певний префікс. У javascript я не знаю, який клас із групи знаходиться на діві. Я хочу мати можливість очистити всі класи із заданим префіксом, а потім додати новий. Якщо я хочу видалити всі класи, які починаються з "bg", як це зробити? Щось подібне, але це насправді працює:

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

Відповіді:


59

З jQuery фактичний елемент DOM знаходиться на рівні нуля, це має працювати

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

34
Обережно з цим. Межа слова розбивається на символ тире ('-') та крапки та інші, тому назви класів типу "bg.a", "bg-a" тощо не будуть видалені, а замінені на ".a", "-a" тощо Отже, якщо у вас є назви класів із знаками пунктуації, ви можете зіткнутися з проблемою, просто запустивши просту замість регулярного вираження. Ось нитка SO щодо визначення межі слова
Якуб П.

6
Відповідь Кабіра Саріна нижче з розділенням ('') та indexOf - краще ІМО, оскільки це не призведе до появи цих спеціальних класів "зомбі".
Якуб П.

2
Цей метод все ще може бути використаний з більш регулярним виразом, наприклад , як один тут: stackoverflow.com/a/2644364/1333402
ssmith

109

Розбиття регулярних виразів на межі слова \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 (перевірка межі слова), оскільки це заважає "класам зомбі" спливати. Якщо у вас є класи типу "префікс-суфікс", "найкраща відповідь" у цій темі залишить клас "-суфікс", оскільки \ b розділиться раніше "-" char. Ваше рішення про приєднання роздільної карти працює навколо цього :) Я створив крихітний плагін jQuery навколо вашого рішення, Кабір: ( gist.github.com/2881585 )
Якуб П.

3
+1 Я також погоджуюсь, що кожна інша відповідь є просто простим виразом, який би розпадався на межі слова, що не є пробілами. Якщо завтра у мене буде час, я поставлю тест, який це підтверджує.
гергес

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(" "));
Тім

Більш правильне рішення використовує карту:$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(" "));.
Альберт

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, це найкращий підхід.
Діней

3

http://www.mail-archive.com/jquery-en@googlegroups.com/msg03998.html сказано:

... і .removeClass () видалить усі класи ...

Це працює для мене;)

ура


Це кращий вибір! Працює.
Афшин Мехрабані

12
Питання не запитує, як видалити всі класи, він запитує, як видалити всі класи, починаючи з певного рядка. Ці дві речі дуже і дуже відрізняються.
Кріс Харрісон

3

Підхід, який я б застосував із використанням простих конструкцій jQuery та функцій обробки масиву, полягає у оголошенні функції, яка приймає ідентифікатор керування та префіксу класу та видаляє всі класифіковані. Код додається:

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

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

2

Для сучасних браузерів:

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

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

1

Я знаю, що це старе питання, але я знайшов нове рішення і хочу знати, чи є у нього недоліки?

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

1

В одному рядку ... Видаляє всі класи, які відповідають регулярному виразу someRegExp

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

0

Відповідь Престаула була корисною, але це не дуже спрацювало для мене. Спосіб 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
Я не думаю, що ти дуже добре читаєш питання. Користувач не питав про просто видалення класу та додавання ще одного.
Ендрю Барбер

1
@Andrew Barber: ти маєш рацію, це не правильна відповідь, але майорск8 запропонував, як очистити всі класи (RemoveAttr), не лише один;)
Tilt
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.