Удалите все классы, которые начинаются с определенной строки

У меня есть div с id = "a", к которому может быть прикреплено любое количество классов из нескольких групп. У каждой группы есть свой префикс. В javascript я не знаю, какой класс из группы находится в div. Я хочу иметь возможность очистить все классы с заданным префиксом, а затем добавить новый. Если я хочу удалить все классы, начинающиеся с «bg», как мне это сделать? Что-то вроде этого, но это действительно работает:

$("#a").removeClass("bg*");
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
101
0
108 372
15
Перейти к ответу Данный вопрос помечен как решенный

Ответы 15

Чтобы справиться с этим, вам не нужен какой-либо специальный код 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;
}

Ответ Престола был полезен, но для меня это не совсем сработало. Способ jQuery для выбора объекта по идентификатору не работал. Мне пришлось использовать

document.getElementById("a").className

вместо

$("#a").className

или $ ("# a") [0]. Имя класса как Имя класса доступно только в элементе DOM, а не в объекте jQuery

Naeem Sarfraz 17.12.2009 13:25

это комментарий для чьего-то ответа, а не ответ

T J 08.12.2015 13:10
Ответ принят как подходящий

С jQuery фактический элемент DOM имеет нулевой индекс, это должно работать

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

Осторожнее с этим. Граница слова разделяется на тире ('-'), точки и другие, поэтому имена классов, такие как «bg.a», «bg-a» и т. д., Не будут удалены, а заменены на «.a», «-a» и т. .Поэтому, если у вас есть имена классов с знаками препинания, вы можете столкнуться с проблемами, просто выполнив простую замену регулярного выражения. Вот SO-поток об определении границы слова

Jakub P. 06.06.2012 16:00

Ответ Кабира Сарина ниже с split ('') и indexOf лучше IMO, потому что он не вызовет всплывающие классы «зомби» со специальными символами.

Jakub P. 06.06.2012 16:29

Этот метод все еще можно использовать с улучшенным регулярным выражением, например, с тем, что можно найти здесь: stackoverflow.com/a/2644364/1333402

ssmith 07.02.2014 04:05

http://www.mail-archive.com/[email protected]/msg03998.html говорит:

... и .removeClass () удалит все классы ...

Меня устраивает ;)

ваше здоровье

Это лучший выбор! Работает.

Afshin Mehrabani 01.07.2012 00:12

Вопрос не спрашивает, как удалить все классы, он спрашивает, как удалить все классы, начинающиеся с определенной строки. Эти две вещи очень, очень разные.

Chris Harrison 26.06.2013 17:14

Я также использую дефис и цифры для имени класса. Итак, моя версия включает '\ d-'

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

Я написал простой Плагин jQuery - alterClass, который удаляет подстановочный класс. При желании также добавлю классы.

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

Спасибо, Пит! Просто использовал ваш плагин, и он отлично работает ... сэкономил мне время!

jordan.baucke 04.05.2012 00:25

Разделение регулярного выражения на границе слова \b - не лучшее решение для этого:

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

или как примесь 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;
};

Обновление ES6 2018:

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

Это лучший подход, чем использование RegExp с \ b (проверка границы слова), потому что он предотвращает появление «классов зомби». Если у вас есть такие классы, как «префикс-суффикс», «лучший ответ» в этом потоке будет оставлять класс «-суффикс», потому что \ b разделится до символа «-». Ваше решение split-map-join работает вокруг этого :) Я создал крошечный плагин jQuery для вашего решения, Kabir: (gist.github.com/2881585)

Jakub P. 06.06.2012 16:32

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

gerges 14.06.2012 09:10

Мне это нравится, хотя на самом деле это недопустимый код, поскольку анонимная функция в 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 13.10.2013 17:43

Более действительное решение использует карту: $e.attr('class', $.map($e.attr('class').split(' '), function (klass) { return klass.indexOf(prefix) != 0 ? klass : undefined; }).join(' '));

M Miller 07.07.2014 05:31

Этот подход работает лучше всего. Я использовал плагин @JakubP. Одно предложение, если можно: что он делает, когда он теперь возвращает классы, это вызывает много места. Например, class = "blackRow blackText orangeFace blackHead" вернет class = " orangeFace ", если вы запустите removeClassPrefix("black");. Я решил это, обрезав результат так: el.className = $.trim(classes.join(" "));.

Albert 23.07.2014 10:35

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

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

В 2020 году недостаток - jQuery.

connexo 05.10.2020 14:46

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

$("#element").removeAttr("class").addClass("yourClass");

Не думаю, что вы хорошо прочитали вопрос. Пользователь не просил просто удалить класс и добавить еще один.

Andrew Barber 13.02.2013 18:34

@Andrew Barber: вы правы, это неправильный ответ, но majorsk8 предложил, как очистить все классы (removeAttr), а не только один;)

Tilt 11.09.2014 13:54

Использование 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 03.09.2015 14:44

Искал решение точно такой же проблемы. Чтобы удалить все классы, начинающиеся с префикса «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 18.03.2014 08:37

Подход, который я бы использовал с использованием простых конструкций 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");

В одну строчку ... Удаляет все классы, соответствующие регулярному выражению someRegExp

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

Для современных браузеров:

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

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

использование string.starsWith () (или string.endsWith ()) было идеальным для меня!

Luke 15.01.2021 19:10

Другие вопросы по теме