Статьи

Изучение API classList

Со времени создания HTML и появления первых веб-сайтов разработчики и дизайнеры пытались настроить внешний вид своих страниц. Эта потребность стала настолько важной, что был создан стандарт, называемый CSS, для правильного управления стилем и отделения его от контента. На современных интерактивных веб-сайтах вам часто нужно добавлять, удалять или переключать имена классов (обычно называемые «классами CSS»). Исторически иметь дело с этими изменениями в JavaScript было немного сложнее, потому что не было встроенных методов для выполнения этих действий. Так было до тех пор, пока HTML5 не представил API ClassList. В этой статье мы узнаем, как работает этот API и какие методы он предоставляет.

Примечание. Термин «CSS-классы» часто используется для обозначения имен классов. Это строки, которые вы помещаете в атрибут class элемента. Тем не менее, есть интересная статья, предполагающая, что термин является неправильным, и вам следует избегать его. Для краткости в этой статье я собираюсь использовать термин «классы» в качестве ярлыка для «имен классов».

Что такое API ClassList?

API classList предоставляет методы и свойства для управления именами классов элементов DOM. Используя его, мы можем выполнять такие операции, как добавление и удаление классов или проверка наличия данного элемента в элементе. API classList предоставляет эти методы и свойства через атрибут элемента DOM, называемый classList . Этот атрибут имеет тип DOMTokenList и содержит следующие методы и свойства:

  • add(class1, class2, ...) : добавляет один или несколько классов в список классов элемента.
  • contains(class) : Возвращает true если список классов содержит данный параметр, и false противном случае.
  • item(index) : возвращает класс с index позиции или null если число больше или равно длине списка. Индекс начинается с нуля, что означает, что имя первого класса имеет индекс 0.
  • length : это свойство только для чтения, которое возвращает количество классов в списке.
  • remove(class1, class2, ...) : Удаляет один или несколько классов из списка классов элемента.
  • toString() : возвращает список классов элемента в виде строки.
  • toggle(class[, force]) : Удаляет данный класс из списка классов и возвращает false . Если класс не существует, он добавляется, и функция возвращает true . Если указан второй аргумент, он будет принудительно добавлять или удалять класс в зависимости от его достоверности. Например, если задать для этого значения значение true класс будет добавлен независимо от того, существует он или нет. Если установить для этого значения значение false , класс будет удален.

Если вы знакомы с jQuery, вы можете подумать, что методы add() и remove() выполняют одну и ту же операцию для нескольких классов, передавая список имен классов, разделенных пробелами (например, add("red bold bigger") ) , Это не вариант. Чтобы добавить или удалить больше классов одновременно, вы должны передать строку для каждого класса (например, add("red", "bold", "bigger") ). Как я указывал, метод toggle() имеет необязательный аргумент, который мы можем использовать для принудительного выполнения заданного действия. Другими словами, если второй параметр toggle() имеет значение false , он действует как метод remove() ; если второй параметр имеет значение true , он действует как метод add() .

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

 <span id="element" class="description"></span> 

Добавление класса

Чтобы добавить имя класса «красный» к атрибуту class элемента, мы можем написать следующее:

 document.getElementById('element').classList.add('red'); // class="description red" 

Чтобы добавить несколько классов, например «красный» и «жирный», мы можем написать это:

 document.getElementById('element').classList.add('red', 'bold'); // class="description red bold" 

Обратите внимание, что если один из предоставленных классов уже присутствует, он не будет добавлен снова.

Удаление класса

Чтобы удалить класс, например, «описание», мы бы написали следующее:

 document.getElementById('element').classList.remove('description'); // class="" 

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

 document.getElementById('element').classList.remove('description', 'red'); // class="" 

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

Переключение класса

Иногда нам нужно добавить или удалить имя класса в зависимости от взаимодействия с пользователем или состояния сайта. Это выполняется с помощью метода toggle() , как показано ниже.

 document.getElementById('element').classList.toggle('description'); // class="" document.getElementById('element').classList.toggle('description'); // class="description" 

Получение класса

API classList предоставляет метод получения имен классов на основе его позиции в списке классов. Допустим, мы хотим получить первый и третий классы нашего элемента. Мы бы написали следующее:

 document.getElementById('element').classList.item(0); // returns "description" document.getElementById('element').classList.item(2); // returns null 

Получение количества классов

Хотя это и не очень часто, в некоторых случаях нам может понадобиться узнать количество классов, примененных к данному элементу. API classList позволяет нам получить этот номер через свойство length как показано ниже:

 console.log(document.getElementById('element').classList.length); // prints 1 

Определить, существует ли класс

Иногда мы можем захотеть выполнить данное действие, основываясь на присутствии определенного класса. Для выполнения теста мы используем метод contains() следующим образом:

 if (document.getElementById('element').classList.contains('description')) { // do something... } else { // do something different... } 

Возвращение списка классов в виде строки

Чтобы вернуть список классов в виде строки, мы можем использовать метод toString() , который показан ниже.

 console.log(document.getElementById('element').classList.toString()); // prints "description" document.getElementById('element').classList.add('red', 'bold'); console.log(document.getElementById('element').classList.toString()); // prints "description red bold" 

Совместимость браузера

ClassList API широко поддерживается в настольных и мобильных браузерах, за исключением Internet Explorer. IE начал поддерживать этот API начиная с версии 10. Более конкретно, вы можете использовать этот API в Chrome 8+, Firefox 3.6+, Internet Explorer 10+, Safari 5.1+ и Opera 11.5+. Как мы видели, API classList очень прост, и, как вы можете догадаться, заполнить его не сложно. Создание собственного полифилла должно быть простым, но если вы хотите что-то, что уже существует, вы можете использовать classList.js от Eli Grey.

демонстрация

Этот раздел предоставляет простую демонстрацию, которая позволяет вам экспериментировать с концепциями, описанными в этой статье. Демонстрационная страница содержит два основных поля: элемент select содержащий методы и свойства, предоставляемые API, и текстовое поле, в которое мы можем записать параметры для передачи. Как вы увидите, демо явно не вызывает методы, но вместо этого использует простой трюк (использование метода JavaScript apply() ), что приводит к меньшему количеству строк кода. Поскольку некоторые браузеры не поддерживают API, мы выполняем проверку, а в случае неудачи мы отображаем сообщение «API не поддерживается». Если браузер поддерживает API classList, мы присоединяем прослушиватель для события click кнопки, чтобы после щелчка мы выполняли выбранный метод.

Демонстрационная версия кода доступна здесь .

 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>ClassList API Demo</title> <style> body { max-width: 500px; margin: 2em auto; font-size: 20px; } h1 { text-align: center; } .hidden { display: none; } .field-wrapper { margin-top: 1em; } #log { height: 200px; width: 100%; overflow-y: scroll; border: 1px solid #333333; line-height: 1.3em; } .button-demo { padding: 0.5em; margin: 1em; } .author { display: block; margin-top: 1em; } </style> </head> <body> <h1>ClassList API</h1> <h3>Live sample element</h3> <div id="showcase"> &lt;span id="play-element" class="description"&gt;&lt;/span&gt; </div> <h3>Play area</h3> <div> <div class="field-wrapper"> <label for="method">Methods and Properties:</label> <select id="method"> <option value="add">add()</option> <option value="contains">contains()</option> <option value="item">item()</option> <option value="length">length</option> <option value="remove">remove()</option> <option value="toString">toString()</option> <option value="toggle">toggle()</option> </select> </div> <div class="field-wrapper"> <label for="parameter">Parameters (use spaces for multiple parameters):</label> <input type="text" id="parameter"></input> </div> <button id="execute" class="button-demo">Execute</button> </div> <span id="d-unsupported" class="hidden">API not supported</span> <h3>Log</h3> <div id="log"></div> <button id="clear-log" class="button-demo">Clear log</button> <span id="play-element" class="description"></span> <script> if (!'classList' in document.createElement('span')) { document.getElementById('c-unsupported').classList.remove('hidden'); document.getElementById('execute').setAttribute('disabled', 'disabled'); } else { var playElement = document.getElementById('play-element'); var method = document.getElementById('method'); var parameter = document.getElementById('parameter'); var log = document.getElementById('log'); var showcase = document.getElementById('showcase'); document.getElementById('clear-log').addEventListener('click', function() { log.innerHTML = ''; }); document.getElementById('execute').addEventListener('click', function() { var message = method.value; if (method.value === 'length') { message += ': ' + playElement.classList[method.value] } else { var result = playElement.classList[method.value].apply(playElement.classList, parameter.value.split(' ')); showcase.textContent = playElement.outerHTML; if (method.value === 'add' || method.value === 'remove' || method.value === 'toggle') { message += ' class "' + parameter.value + '"'; } else { message += ': ' + result; } } log.innerHTML = message + '<br />' + log.innerHTML; }); } </script> </body> </html> 

Выводы

В этой статье мы узнали об API classList, его методах и свойствах. Как мы уже видели, этот API помогает нам управлять классами, назначенными данному элементу, и его очень легко использовать и. Этот API широко поддерживается в настольных и мобильных браузерах, поэтому мы можем использовать его безопасно (с помощью полифилла, если это необходимо). И последнее замечание: не забудьте поиграть с демоверсией, чтобы лучше понять этот API и его возможности.