Как изменить класс элемента с помощью JavaScript? - PullRequest
2532 голосов
/ 13 октября 2008

Как изменить класс элемента HTML в ответ на событие onclick с использованием JavaScript?

Ответы [ 28 ]

3616 голосов
/ 13 октября 2008

Современные методы HTML5 для изменения классов

Современные браузеры добавили classList , который предоставляет методы, облегчающие манипулирование классами без использования библиотеки:

document.getElementById("MyElement").classList.add('MyClass');

document.getElementById("MyElement").classList.remove('MyClass');

if ( document.getElementById("MyElement").classList.contains('MyClass') )

document.getElementById("MyElement").classList.toggle('MyClass');

К сожалению, они не работают в Internet Explorer до v10, хотя существует shim для добавления поддержки для IE8 и IE9, доступный с на этой странице . Однако все больше и больше поддерживается .

Простое кросс-браузерное решение

Стандартный способ выбора элемента в JavaScript - это document.getElementById("Id"), который используют следующие примеры - вы, конечно, можете получить элементы другими способами, а в правильной ситуации можете просто использовать this вместо этого - однако, вдаваться в подробности по этому вопросу выходит за рамки ответа.

Чтобы изменить все классы для элемента:

Чтобы заменить все существующие классы одним или несколькими новыми классами, установите атрибут className:

document.getElementById("MyElement").className = "MyClass";

(Вы можете использовать разделенный пробелами список для применения нескольких классов.)

Чтобы добавить дополнительный класс к элементу:

Чтобы добавить класс к элементу, не удаляя / не затрагивая существующие значения, добавьте пробел и новое имя класса, например, так:

document.getElementById("MyElement").className += " MyClass";

Чтобы удалить класс из элемента:

Чтобы удалить отдельный класс для элемента, не затрагивая другие потенциальные классы, требуется простая замена регулярного выражения:

document.getElementById("MyElement").className =
   document.getElementById("MyElement").className.replace
      ( /(?:^|\s)MyClass(?!\S)/g , '' )
/* Code wrapped for readability - above is all one statement */

Объяснение этого регулярного выражения следующее:

(?:^|\s) # Match the start of the string, or any single whitespace character

MyClass  # The literal text for the classname to remove

(?!\S)   # Negative lookahead to verify the above is the whole classname
         # Ensures there is no non-space character following
         # (i.e. must be end of string or a space)

Флаг g указывает замене повторяться при необходимости, если имя класса было добавлено несколько раз.

Чтобы проверить, применяется ли класс к элементу:

То же регулярное выражение, которое использовалось выше для удаления класса, также можно использовать для проверки существования определенного класса:

if ( document.getElementById("MyElement").className.match(/(?:^|\s)MyClass(?!\S)/) )


Назначение этих действий событиям клика:

Хотя можно писать JavaScript непосредственно внутри атрибутов событий HTML (например, onclick="this.className+=' MyClass'"), такое поведение не рекомендуется. Особенно в более крупных приложениях более понятный код достигается путем отделения разметки HTML от логики взаимодействия JavaScript.

Первый шаг к достижению этого - создание функции и вызов функции в атрибуте onclick, например:

<script type="text/javascript">
    function changeClass(){
        // Code examples from above
    }
</script>
...
<button onclick="changeClass()">My Button</button>

(Не обязательно иметь этот код в тегах скрипта, это просто для краткости примера, и более подходящим может быть включение JavaScript в отдельный файл.)

Второй шаг - переместить событие onclick из HTML в JavaScript, например, с помощью addEventListener

<script type="text/javascript">
    function changeClass(){
        // Code examples from above
    }

    window.onload = function(){
        document.getElementById("MyElement").addEventListener( 'click', changeClass);
    }
</script>
...
<button id="MyElement">My Button</button>

(Обратите внимание, что часть window.onload требуется для того, чтобы содержимое этой функции выполнялось после , когда HTML завершил загрузку - без этого MyElement может не существовать, когда вызывается код JavaScript, так что эта линия потерпит неудачу.)


JavaScript фреймворки и библиотеки

Вышеприведенный код написан на стандартном JavaScript, однако общепринятой практикой является использование инфраструктуры или библиотеки для упрощения общих задач, а также использования исправленных ошибок и крайних случаев, о которых вы могли не подумать при написании кода. .

Хотя некоторые люди считают излишним добавлять ~ 50 КБ фреймворка для простого изменения класса, если вы выполняете какой-либо значительный объем работы с JavaScript или что-то, что может иметь необычное поведение в разных браузерах, это стоит рассмотреть.

(Грубо говоря, библиотека - это набор инструментов, предназначенных для конкретной задачи, в то время как среда обычно содержит несколько библиотек и выполняет полный набор обязанностей.)

Приведенные выше примеры были воспроизведены ниже с использованием jQuery , вероятно, наиболее часто используемой библиотеки JavaScript (хотя есть и другие, которые тоже стоит изучить).

(Обратите внимание, что $ здесь - это объект jQuery.)

Изменение классов с помощью jQuery:

$('#MyElement').addClass('MyClass');

$('#MyElement').removeClass('MyClass');

if ( $('#MyElement').hasClass('MyClass') )

Кроме того, jQuery предоставляет ярлык для добавления класса, если он не применяется, или удаления класса, который делает:

$('#MyElement').toggleClass('MyClass');


Назначение функции событию щелчка с помощью jQuery:

$('#MyElement').click(changeClass);

или без идентификатора:

$(':button:contains(My Button)').click(changeClass);


398 голосов
/ 05 августа 2011

Вы также можете просто сделать:

document.getElementById('id').classList.add('class');
document.getElementById('id').classList.remove('class');

И переключить класс (удалить, если существует, добавить его):

document.getElementById('id').classList.toggle('class');
108 голосов
/ 28 мая 2011

В одном из моих старых проектов, в которых не использовался jQuery, я создал следующие функции для добавления, удаления и проверки, имеет ли элемент класс:

function hasClass(ele, cls) {
    return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}
function addClass(ele, cls) {
    if (!hasClass(ele, cls)) ele.className += " " + cls;
}
function removeClass(ele, cls) {
    if (hasClass(ele, cls)) {
        var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
        ele.className = ele.className.replace(reg, ' ');
    }
}

Так, например, если я хочу, чтобы onclick добавил какой-то класс, кнопку, я могу использовать это:

<script type="text/javascript">
    function changeClass(btn, cls) {
        if(!hasClass(btn, cls)) {
            addClass(btn, cls);
        }
    }
</script>
...
<button onclick="changeClass(this, "someClass")">My Button</button>

К настоящему времени наверняка было бы лучше использовать jQuery.

71 голосов
/ 13 октября 2008

Вы можете использовать node.className примерно так:

document.getElementById('foo').className = 'bar';

Это должно работать в IE5.5 и выше в соответствии с PPK .

46 голосов
/ 05 января 2012

Ух ты, удивляешься, что здесь так много ответов о перегибах ...

<div class="firstClass" onclick="this.className='secondClass'">
45 голосов
/ 20 сентября 2011

Использование чистого кода JavaScript:

function hasClass(ele, cls) {
    return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}

function addClass(ele, cls) {
    if (!this.hasClass(ele, cls)) ele.className += " " + cls;
}

function removeClass(ele, cls) {
    if (hasClass(ele, cls)) {
        var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
        ele.className = ele.className.replace(reg, ' ');
    }
}

function replaceClass(ele, oldClass, newClass){
    if(hasClass(ele, oldClass)){
        removeClass(ele, oldClass);
        addClass(ele, newClass);
    }
    return;
}

function toggleClass(ele, cls1, cls2){
    if(hasClass(ele, cls1)){
        replaceClass(ele, cls1, cls2);
    }else if(hasClass(ele, cls2)){
        replaceClass(ele, cls2, cls1);
    }else{
        addClass(ele, cls1);
    }
}
31 голосов
/ 08 декабря 2011

Это работает для меня:

function setCSS(eleID) {
    var currTabElem = document.getElementById(eleID);

    currTabElem.setAttribute("class", "some_class_name");
    currTabElem.setAttribute("className", "some_class_name");
}
19 голосов
/ 11 апреля 2013

Также вы можете расширить объект HTMLElement, чтобы добавить методы для добавления, удаления, переключения и проверки классов ( gist ):

HTMLElement = typeof(HTMLElement) != 'undefiend' ? HTMLElement : Element;

HTMLElement.prototype.addClass = function(string) {
  if (!(string instanceof Array)) {
    string = string.split(' ');
  }
  for(var i = 0, len = string.length; i < len; ++i) {
    if (string[i] && !new RegExp('(\\s+|^)' + string[i] + '(\\s+|$)').test(this.className)) {
      this.className = this.className.trim() + ' ' + string[i];
    }
  }
}

HTMLElement.prototype.removeClass = function(string) {
  if (!(string instanceof Array)) {
    string = string.split(' ');
  }
  for(var i = 0, len = string.length; i < len; ++i) {
    this.className = this.className.replace(new RegExp('(\\s+|^)' + string[i] + '(\\s+|$)'), ' ').trim();
  }
}

HTMLElement.prototype.toggleClass = function(string) {
  if (string) {
    if (new RegExp('(\\s+|^)' + string + '(\\s+|$)').test(this.className)) {
      this.className = this.className.replace(new RegExp('(\\s+|^)' + string + '(\\s+|$)'), ' ').trim();
    } else {
      this.className = this.className.trim() + ' ' + string;
    }
  }
}

HTMLElement.prototype.hasClass = function(string) {
  return string && new RegExp('(\\s+|^)' + string + '(\\s+|$)').test(this.className);
}

А потом просто используйте вот так (по клику добавит или удалит класс):

document.getElementById('yourElementId').onclick = function() {
  this.toggleClass('active');
}

Вот демо .

16 голосов
/ 27 ноября 2011

Просто для добавления информации из другого популярного фреймворка, Google Closures, посмотрите их dom / classes class:

goog.dom.classes.add(element, var_args)

goog.dom.classes.addRemove(element, classesToRemove, classesToAdd)

goog.dom.classes.remove(element, var_args)

Одним из вариантов выбора элемента является использование goog.dom.query с селектором CSS3:

var myElement = goog.dom.query("#MyElement")[0];
13 голосов
/ 02 мая 2012

Несколько мелких заметок и изменений в предыдущих регулярных выражениях:

Вы захотите сделать это глобально, если список классов будет иметь имя класса более одного раза. И вы, вероятно, захотите убрать пробелы из концов списка классов и преобразовать несколько пробелов в один пробел, чтобы избежать получения пробелов. Ничто из этого не должно быть проблемой, если единственный код, помеченный именами классов, использует приведенное ниже регулярное выражение и удаляет имя перед его добавлением. Но. Ну, кто знает, кто может пить из списка имен классов.

Это регулярное выражение нечувствительно к регистру, поэтому ошибки в именах классов могут появляться до того, как код будет использован в браузере, который не заботится о регистре в именах классов.

var s = "testing   one   four  one  two";
var cls = "one";
var rg          = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
alert("[" + s.replace(rg, ' ') + "]");
var cls = "test";
var rg          = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
alert("[" + s.replace(rg, ' ') + "]");
var cls = "testing";
var rg          = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
alert("[" + s.replace(rg, ' ') + "]");
var cls = "tWo";
var rg          = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
alert("[" + s.replace(rg, ' ') + "]");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...