Управление классами и стилями элементов в JavaScript

Александр Мальцев
Александр Мальцев
33K
17
Содержание:
  1. Управление классом (классами) элемента
  2. Стили элемента
  3. Задания
  4. Комментарии

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

Управление классом (классами) элемента

Первый способ взаимодействия с классами элементов сводится к использованию DOM-свойства className. Данное свойство является отражением атрибута class в DOM. DOM-свойство className не было названо class из-за того, что раньше в JavaScript зарезервированные слова нельзя было использовать в качестве названия свойств объектов. Если вы не знаете, что такое DOM-свойства и чем они отличаются от атрибутов, то прочитать про это можете в этой статье.

Пример, в котором выполним различные операции над классом элемента используя DOM-свойство className:

<p id="alert">...</p>

<script>
var elem = document.querySelector('#alert');
// добавим класс к элементу
elem.className = 'alert'; // "alert"
// изменим класс у элемента
elem.className = 'alert-warning'; // "alert-warning"
// получим значение класса и сохраним его в className
var classElem = elem.className; // "alert-warning"
// удалим класс у элемента
elem.className = ""; // ""
</script>

Второй способ выполнить операции, связанные с классом элемента – это использовать методы для управления атрибутами.

Пример, в котором выполним действия как вышеприведённом коде, но с использованием методов для управления атрибутами:

<p id="alert">...</p>

<script>
var elem = document.querySelector('#alert');
// добавим класс к элементу
elem.setAttribute('class', 'alert');
// изменим класс у элемента
elem.setAttribute('class', 'alert-warning');
// получим значение класса и сохраним его в className
var classElem = elem.getAttribute('class'); // "alert-warning"
// удалим класс у элемента
elem.removeAttribute('class');
</script>

DOM-свойство className и атрибут class всегда синхронизуются между собой, это значит, что при изменении одного меняется и другое.

Но у элемента может быть не один класс, а несколько. В этом случае работать с ними как со строкой не очень удобно.

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

Пример, в котором проверим наличие у элемента класса content__show:

<div id="content" class="content content__show">...</div>

<script>
  var elem = document.querySelector('#content');
  if ((' ' + elem.className + ' ').indexOf(' content__show ') > -1) {
    // у элемента есть класс content__show
  } else {
    // у элемента класса content__show нет
  }
</script>

Но кроме этой ситуации, встречаются и другие. Например, когда нужно добавить какой-то один определённый класс к элементу, или удалить его. Чтобы эти действия и другие производить очень просто у элемента есть специальное для этих случаев DOM-свойство classList.

Свойство classList

Свойство classList представляет собой специальный объект (DOMTokenList), который содержит методы для выполнения различных операций над классами элемента.

Методы classList:

  • .add( className1[,className2,...] ) - добавляет один или несколько указанных классов к элементу. Если у элемента уже есть данный класс, то он к нему добавлен не будет.
  • .remove( className1[,className2,... ] ) - удаляет один или несколько указанных классов у элемента. Если у элемента нет класса, который вы хотите удалить, то никаких действий произведено не будет.
  • .contains( className ) – проверяет наличие класса у элемента; в качестве ответа возвращает true или false.
  • .toggle( className [,flag] ) - переключает указанное имя класса у элемента, т.е. если у элемента есть данный класс, то убирает его; в противном случае добавляет. Второй параметр (flag) необязательный. По умолчанию он имеет значение undefined. Если ему установить значение true или false, то он будет работать как метод add или remove, т.е. либо добавлять класс к элементу, либо удалять его у него.

Пример, в котором показано как можно выполнять различные действия, связанные с классами элемента с использованием методов classList:

// получим элемент c id="sidebar"
const sideBar = document.querySelector('#sidebar');

// переключим класс hidden-xs у элемента, т.е. если он есть он у элемента, то удалим его; а если данного класса нет, то добавим его к нему
sideBar.classList.toogle('hidden-xs');
// добавим три дополнительных класса
sideBar.classList.add('col-xs-6', 'col-sm-4', 'col-md-3');
// удалим класс hidden-xs
sideBar.classList.remove('hidden-xs');
// проверим есть ли класс hidden-lg у элемента и если есть, то добавим к нему ещё один hidden-md
if (sideBar.classList.contains('hidden-lg')) {
  sideBar.classList.add('hidden-md');
}

Объект classList является псевдомассивом, т.е. его можно перебрать как массив.

Пример, в котором переберём все классы classList:

<div class="content col-12 col-sm-8 col-md-6">...</div>

<script>
var content = document.querySelector('.content');

// Вариант №1. С помощью цикла for
// classList.length - количество классов у элемента
// отсчёт классов в classList ведётся с 0
for (var i = 0, length = content.classList.length; i < length; i++) {
  // i - индекс класса в classList
  // выведем класс в консоль
  console.log(content.classList[i]);
  // или так (с помощью метода item)
  console.log(content.classList.item(i));  
}
// если мы хотим получить класс по его индексу, а указали в качестве значения индекса число, которое больше, чем (количества элементов - 1) в classList (т.к. отсчет ведётся с 0), то в этом случае получим в качестве результата undefined
console.log(content.classList[7]); // undefined

// Вариант №2. С помощью цикла for..of
for (let className of content.classList) {
  // выведем класс в консоль
  console.log(className);
}
</script>

Свойство classList поддерживается всеми современными браузерами. Если нужна поддержка совсем старых браузеров (например, Internet Explorer 8, 9), то в этом случае можно воспользоваться каким-нибудь полифиллом.

Стили элемента

В DOM у каждого элемента есть свойство style, с помощью которого мы можем управлять его стилями. Значение данного свойства — это объект, который доступен только для чтения. Установка стилей элементу в этом случае осуществляется посредством добавления к нему соответствующих свойств.

Пример, как можно к элементу добавить стили через DOM-свойство style:

<div class="square">Квадрат</div>

<script>
const square = document.querySelector('.square');
square.style.width = '170px';
square.style.height = '170px';
square.style.backgroundColor = 'green';
</script>

Имена свойств объекта style обычно совпадают с названиями CSS-свойств. Исключение составляют только те CSS-свойства, в которых используется дефис. Например, background-color. В этом случае дефис и следующая за ним буква заменяется на прописную. Например, CSS-свойство background-color для объекта style будет указывать как backgroundColor. А, например, CSS-свойство с браузерным префиксом -webkit-border-radius - как WebkitBorderRadius.

Удаление стилей

Например, установим body некоторый цвет фона:

document.body.style.backgroundColor = '#eee';

Если теперь данный стиль нужно убрать, то чтобы это выполнить мы должны просто присвоить ему пустую строку:

document.body.style.backgroundColor = '';

Примеры использования DOM-свойства style для установки стилей элементам.

<p id="introtext" style="font-weigth: bold;">...</p>
<p>...</p>
<p>...</p>

<script>
// установим элементу с id = "introtext" с использованием style красный цвет текста 
document.querySelector('#introtext').style.color = 'red';

// установим всем элементам p на странице с использованием style зелёный цвет текста
var paragraphs = document.querySelectorAll("p");
for (var i = 0, length = paragraphs.length; i < length; i++) { 
  paragraphs[i].style.backgroundColor = 'green';
}

// выведем в консоль все CSS свойства элемента с идентификатором "introtext"
var styleElem = document.querySelector('#introtext').style;
for (var i = 0, length = styleElem.length; i < length; i++) { 
  console.log(styleElem[i]);
}
</script>

Свойство cssText

Кроме индивидуального установления стилей элементу мы можем установить их сразу с помощью специального свойства style.cssText. Осуществляется это посредством присваивания этому свойству строки, состоящей из набора стилей, разделённых между собой с помощью точки с запятой. Т.е. выполняется это аналогично тому, как мы устанавливаем стили в HTML-атрибуте style.

Пример, в котором установим стили "font-size:40px; color:blue;" элементам с классом intro:

<p class="intro">...</p>

<script>
  //получим все элементы с классом intro
  const introList = document.querySelectorAll('.intro');

  //установим "font-size:40px; color:blue;" всем элементам в introList
  for (let i = 0, length = introList.length; i < length; i++) {
    introList[i].style.cssText = 'font-size:40px; color:blue;';
  }
</script>

При установке стилей с помощью свойства style.cssText нужно быть осторожным. Эти связано с тем, что при установке это свойство удаляет все стили, которые есть у элемента. Т.е. те, которые мы установили ему с помощью атрибута style и в соответствующем ему DOM-свойстве.

Выполнить операцию, аналогичную той которую выполняет свойство style.cssText, можно ещё через метод setAttribute.

Например:

<p class="info">...</p>

<script>
//получим первый элемент с классом info
const info = document.querySelector('.info');

//установим ему стиль "margin: 10px; padding: 10px; border: 1px solid green;"
info.setAttribute('style', 'margin: 10px; padding: 10px; border: 1px solid green;');
</script>

Задания

1. Написать скрипт, используя classList, для установления элементу с классом text трех классов: size-40, color-red и bg-yellow:

<!-- СSS -->
<style> 
  .size-40 {
    font-size: 40px;
  }
  .color-red {
    color: red;
  }
  .bg-yellow {
    background: yellow;
  }
</style>

<!-- HTML -->
<p class="text">Некоторый текст...</p>

2. Написать код для установления стиля "width: 180px; height: 180px;" всем элементам на странице с классом, начинающимся со слов block-.

Комментарии:

  1. Evgen
    Evgen
    12.05.2021, 13:03
    Пример не работает. Если добавить точку перед именем класса '".intro" — работает.

    Пример, в котором установим стили "font-size:40px; color:blue;" элементам с классом intro:
    <p class="intro">...</p>
    <script>
    //получим элементы с классом intro
    var intro = document.querySelectorAll("intro");
    //установим "font-size:40px; color:blue;" всем элементам в коллекции, содержащейся в intro
    for (var i = 0, length = intro.length; i < length; i++) {
      intro[i].style.cssText = "font-size:40px; color:blue;";
    }
    </script>
    
    1. Александр Мальцев
      Александр Мальцев
      12.05.2021, 13:55
      Спасибо, поправил.
    2. Evgen
      Evgen
      12.05.2021, 12:27
      Привет! Супер все объясняешь, очень доступно.

      Пример ниже не работает, пропущено ".style" перед «backgroundColor».
      Пример, как можно к элементу добавить стили через DOM-свойство style:
      <div class="square">Квадрат</div>
      <script>
      var square = document.querySelector('.square');
      square.style.width = '170px';
      square.style.height = '170px';
      square.backgroundColor = 'green';
      </script>
      
      1. Александр Мальцев
        Александр Мальцев
        12.05.2021, 13:58
        Привет! Спасибо за отзыв. Поправил.
      2. Evgen
        Evgen
        11.05.2021, 15:43
        Привет! В самом конце примера myID = sideBar?

          Пример, в котором показано как можно выполнять различные действия, связанные с классами элемента с использованием методов classList:
        
        // получим элемент c id = "sidebar"
        var sideBar = document.querySelector('#sidebar');
        
        // переключим класс hidden-xs у элемента, т.е. если он есть он у элемента, то удалим его; а если данного класса нет, то добавим его к нему
        sideBar.classList.toogle("hidden-xs");
        // добавим три дополнительных класса к элементу
        sideBar.classList.add('col-xs-6','col-sm-4','col-md-3');
        // удалим класс hidden-xs у элемента
        sideBar.classList.remove('hidden-xs');
        // проверим есть ли класс hidden-lg у элемента и если есть, то добавим к нему ещё один hidden-md
        if (sideBar.classList.contains('hidden-lg') {
          myID.classList.add('hidden-md');
        }
        
        1. Александр Мальцев
          Александр Мальцев
          12.05.2021, 14:02
          Привет! Спасибо, поправил.
        2. Sergey
          Sergey
          01.09.2020, 22:10
          Здравствуйте! Столкнулся с проблемой. Хочу поменять url в свойстве background-img. Пишу: (переменная).style.backgroundImage.url = 'папка' + (переменная). где ошибка?

          1. Александр Мальцев
            Александр Мальцев
            02.09.2020, 14:06
            Здравствуйте! Как в CSS:
            // имя файла
            const image = '1.png';
            // elem - переменная, содержащая DOM-элемент
            // assets/images/ - путь до изображения
            elem.style.backgroundImage = 'url(assets/images/' + image + ')';
            
            1. Sergey
              Sergey
              02.09.2020, 16:52
              большое спасибо )
          2. Карим Азиев
            Карим Азиев
            02.12.2016, 11:12
            Я так понимаю, для решения последней задачи нужно использовать click? Но разве он был в предыдущих уроках?
            1. Александр Мальцев
              Александр Мальцев
              03.12.2016, 00:05
              Да, есть такой недочёт. Чтобы не использовать события, эти действия можно выполнить, например, используя консоль браузера.
            2. Maksim
              Maksim
              21.10.2015, 13:55
              Добрый день, Александр.

              есть простая задача, при нажатии кнопки поменять class у элемента.
              сделал два варианта скрипта

              Вариант 1
              <script>
              $('#MyButton').click(function(){
                      $('#myWindow').attr('class', 'visible');
              });
              </script>
              

              Вариант 2
              <script>
              $('#MyButton').click(function(){
                      $('#myWindow).removeClass('hidden');
              });
              </script>  
              Оба варианта работают на всех платформах, кроме браузера Safari. В чем может быть причина?
              1. Александр Мальцев
                Александр Мальцев
                21.10.2015, 15:56
                Здравствуйте!
                Вы используете не чистый JavaScript, а библиотеку jQuery.

                На странице поддержки различных браузеров библиотеками jQuery 1.x и 2.x сказано, что данные версии библиотек поддерживают браузер Safari, начиная с версии 5.1.
                Если данное условие у Вас выполняется, то попробуйте использовать самую последнюю версию библиотеки jQuery (1.11.3 или 2.1.4).
                Если Вам и это не поможет, то попробуйте вместо $ использовать jQuery:
                <script>
                jQuery('#MyButton').click(function(){
                  jQuery('#myWindow').attr('class', 'visible');
                });
                </script>
                
                1. Maksim
                  Maksim
                  21.10.2015, 16:41
                  Спасибо за информацию. пока не сработало, но в каком направлении искать — понял. будут искать.
                  и ещё вопрос попутно, как сделать, чтобы при повторном нажатии на ту же кнопку class менялся обратно?
                  1. Александр Мальцев
                    Александр Мальцев
                    21.10.2015, 17:11
                    В jQuery есть метод .toggleClass(имя_класса). Данный метод переключает указанный класс у элемента. Т.е. если у элемента данного класса нет, то он добавляется. А если указанный класс есть, то он удаляется.
                    $('#idElement').toggleClass('visible');
                    
                    А если Вы заменили класс, а потом Вам его надо вернуть обратно, то здесь только вручную.
                    Т.е. сначала сохраняете значение класса в переменную:
                    // сохранить значение класса в переменную
                    var previousClass = $("#idElement").attr("class");
                    
                    А потом восстанавливаете значение класса из переменной:
                    //восстановить значение класса из переменной
                    $("#idElement").attr("class",previousClass);
                    
                    1. Maksim
                      Maksim
                      21.10.2015, 21:52
                      с восстановлением переменной не осилил, смену атрибута пришлось делать по-другому:
                      <script>
                      $('#eye').click(function(){
                       if ($('#CurrentPass').get(0).type=='password') $('#CurrentPass').get(0).type='text'; 
                      else $('#CurrentPass').get(0).type='password';
                      });    
                      </script> 
                      
                      1. Maksim
                        Maksim
                        21.10.2015, 17:13
                        Спасибо Александр!
                Войдите, пожалуйста, в аккаунт, чтобы оставить комментарий.