Чи є простий спосіб видалити всі класи, які відповідають, наприклад,
color-*
тому якщо у мене є елемент:
<div id="hello" class="color-red color-brown foo bar"></div>
після вилучення було б
<div id="hello" class="foo bar"></div>
Дякую!
Чи є простий спосіб видалити всі класи, які відповідають, наприклад,
color-*
тому якщо у мене є елемент:
<div id="hello" class="color-red color-brown foo bar"></div>
після вилучення було б
<div id="hello" class="foo bar"></div>
Дякую!
Відповіді:
Функція RemoveClass приймає аргумент функції, починаючи з jQuery 1.4 .
$("#hello").removeClass (function (index, className) {
return (className.match (/(^|\s)color-\S+/g) || []).join(' ');
});
Приклад наживо: http://jsfiddle.net/xa9xS/1409/
classes = ( value || "" ).match( rnotwhite ) || [];
sport-, nav-і color-?
*-color?
(color-|sport-|nav-). Він буде відповідати color-, або sport-, або nav-. Отже, відповідь вище стала б /(^|\s)(color-|sport-|nav-)\S+/g.
$('div').attr('class', function(i, c){
return c.replace(/(^|\s)color-\S+/g, '');
});
c is undefined)? Принаймні, коли я спробував це нижче у своєму плагіні на цій сторінці, $('a').stripClass('post', 1)кинув "TypeError: Неможливо викликати метод" замінити "невизначеним"
$('div[class]')слід повертати лише елементи, мають classвони значення чи ні. тестові сценарії: jsfiddle.net/drzaus/m83mv
.removeProp('class')або .className=undefinedфільтр [class]все-таки щось повертає, вони просто undefined. Так технічно він все ще має клас (на відміну від цього .removeAttr('class'), тому він порушує вашу функцію, але не мій варіант. Jsfiddle.net/drzaus/m83mv/4
return c && c.replace(/\bcolor-\S+/g, '');
Я написав плагін, який робить це під назвою alterClass - Видалення класів елементів із відповідним підстановкою. За бажанням додайте класи: https://gist.github.com/1517285
$( '#foo' ).alterClass( 'foo-* bar-*', 'foobar' )
Twitter Boostrapтакі класи:$(".search div").children('div').alterClass('span* row-fluid');
Я узагальнив це у плагіні Jquery, який бере аргумент як аргумент.
Кава:
$.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(' ');
});
};
Отже, у цьому випадку використання буде (і кава, і Javascript):
$('#hello').removeClassRegex(/^color-/)
Зауважте, що я використовую Array.filterфункцію, яка не існує в IE <9. Ви можете замість цього використовувати функцію фільтрування Underscore або Google для поліфункції, такої як WTFPL .
Якщо ви хочете використовувати його в інших місцях, я пропоную вам розширення. Цей добре працює для мене.
$.fn.removeClassStartingWith = function (filter) {
$(this).removeClass(function (index, className) {
return (className.match(new RegExp("\\S*" + filter + "\\S*", 'g')) || []).join(' ')
});
return this;
};
Використання:
$(".myClass").removeClassStartingWith('color');
ми можемо отримати всі класи за допомогою .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)
Подібно @ tremby - х відповіді , ось @ Кобі в відповідь як плагін , який буде відповідати або префікси або суфікси.
btn-miniі , btn-dangerале не btnколи stripClass("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;
};
endOrBeginмає бути. Це не пояснює себе. Що важко написати регулярний вираз? /^match-at-start/і /match-at-end$/відомі кожному розробнику JS. Але кожен по-своєму.
addClass, removeClassі toggleClass, яка , як відомо кожному розробнику JQuery. Що важко з читанням документації? ;)
Для плагіна 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;
};
На основі ARS81 «s відповіді (що відповідає тільки іменами класів , починаючи з), ось більш гнучким варіантом. Також hasClass()версія регулярної виразки.
Використання: $('.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;
};
Це ефективно видалить усі імена класів, що починається з атрибута 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об'єкт один раз з кожного зворотного дзвінка?
У мене була така ж проблема, і я придумав таке, що використовує метод _.filter підкреслення. Як тільки я виявив, що RemoveClass приймає функцію і надає вам список імен класів, було легко перетворити це на масив і відфільтрувати ім'я класу, щоб повернутися назад до методу 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;
});
Ви також можете це зробити за допомогою ванільного 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яке оновлюватиметься після видалення класів.
Ви також можете використовувати classNameвластивість об'єкта DOM елемента:
var $hello = $('#hello');
$('#hello').attr('class', $hello.get(0).className.replace(/\bcolor-\S+/g, ''));
Загальна функція, яка видаляє будь-який клас, починаючи з 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>
Розбиття регулярних виразів на межі слова \b- не найкраще рішення для цього:
var prefix = "prefix";
var classes = el.className.split(" ").filter(function(c) {
return c.lastIndexOf(prefix, 0) !== 0;
});
el.className = classes.join(" ");
або як 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 = classes.join(" ");
});
return this;
};
якщо у вас є більше одного елемента з назвою класу 'example', для видалення класів 'color-' у всіх них ви можете це зробити: [використовуючи 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 -] * у свій регулярний вираз, він не видалить класи, у яких в їхніх назвах є число або "-".
Якщо вам просто потрібно видалити останній встановлений колір, вам може підійти наступний.
У моїй ситуації мені потрібно було додати клас кольорів до тегу тіла під час події клацання та видалити останній встановлений колір. У цьому випадку ви зберігаєте поточний колір, а потім шукаєте тег даних, щоб видалити останній заданий колір.
Код:
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
Можливо, це не саме те, що вам потрібно, але для мене це було, і це було перше питання, яке я подивився, тому подумав, що поділюсь своїм рішенням, якщо це допоможе комусь.
Альтернативний спосіб підходу до цієї проблеми - використання атрибутів даних, які за своєю природою є унікальними.
Ви б встановили колір елемента: $el.attr('data-color', 'red');
І ви б стилізували це в CSS: [data-color="red"]{ color: tomato; }
Це нівелює необхідність використання класів, що має побічний ефект від необхідності видалення старих класів.