Использование селекторов

В библиотеке Tom Sel ect управление элементами интерфейса опирается на предсказуемую DOM-структуру и набор CSS-классов, которые формируют основу для взаимодействия через селекторы. Понимание этих селекторов позволяет точно изменять поведение компонента, стилизовать его и интегрировать с внешними скриптами.

Ключевой контейнер компонента создаётся вокруг исходного <select> элемента и получает класс:

  • .tom-select
  • .ts-wrapper

Внутри этого контейнера формируется набор внутренних узлов:

  • .ts-control — область ввода и отображения выбранных значений
  • .ts-dropdown — выпадающий список
  • .item — выбранный элемент
  • .option — элемент списка
  • .dropdown-content — контейнер опций

Эта структура формирует базу для всех CSS и JavaScript селекторов, используемых в дальнейшем.


Селекторы обёртки и инициализированного компонента

После инициализации Tom Select исходный <select> скрывается, а вокруг него создаётся новый DOM-контейнер. Доступ к нему осуществляется через стандартные DOM-селекторы:

document.querySelector('.ts-wrapper');

или более точечно:

document.querySelector('.ts-wrapper.tom-select');

Если требуется привязка к конкретному экземпляру, используется идентификатор исходного элемента:

<select id="country-select"></select>
document.querySelector('#country-select + .ts-wrapper');

Такой подход позволяет связывать оригинальный элемент и его визуальное представление.


Селекторы внутреннего поля ввода

Поле ввода внутри Tom Select используется для поиска и фильтрации. Оно доступно через класс .ts-control:

const control = document.querySelector('.ts-wrapper .ts-control');

Для получения именно input-элемента внутри control:

const input = document.querySelector('.ts-wrapper .ts-control input');

Особенность структуры заключается в том, что input создаётся динамически только при активации поиска, поэтому селектор может возвращать null до первого взаимодействия.


Селекторы выбранных элементов

Выбранные значения отображаются как элементы с классом .item внутри .ts-control:

const selectedItems = document.querySelectorAll('.ts-wrapper .item');

Каждый элемент содержит атрибут data-value, который соответствует значению опции:

document.querySelectorAll('.ts-wrapper .item[data-value]');

Пример структуры:

<div class="item" data-value="ru">Russia</div>
<div class="item" data-value="kz">Kazakhstan</div>

Фильтрация по конкретному значению:

document.querySelector('.item[data-value="kz"]');

Селекторы выпадающего списка

Выпадающий список активируется при фокусе или вводе текста и помещается в .ts-dropdown.

Основные селекторы:

const dropdown = document.querySelector('.ts-dropdown');
const options = document.querySelectorAll('.ts-dropdown .option');

Каждая опция имеет структуру:

<div class="option" data-value="ru">Russia</div>

Доступ к конкретной опции:

document.querySelector('.ts-dropdown .option[data-value="ru"]');

Состояние активной опции:

document.querySelector('.ts-dropdown .option.active');

Селекторы состояния (active, focus, disabled)

Tom Select активно использует классы состояния для управления визуальной логикой:

  • .active — выбранный или подсвеченный элемент
  • .focus — элемент в фокусе
  • .disabled — заблокированный элемент
  • .selected — отмеченная опция (в зависимости от конфигурации)

Пример выборки активных элементов:

document.querySelectorAll('.ts-wrapper .option.active');

Блокировка селектора:

document.querySelector('.ts-wrapper.disabled');

Селекторы множественного выбора

При включённом режиме maxItems > 1 структура .ts-control содержит несколько .item элементов.

Выбор всех значений:

const values = Array.fr om(
  document.querySelectorAll('.ts-wrapper .item')
).map(el => el.dataset.value);

Удаление отдельного элемента по селектору:

document.querySelector('.item[data-value="ru"]').remove();

При этом важно учитывать, что визуальное удаление не синхронизирует состояние компонента без обращения к API экземпляра.


Селекторы атрибутов data-*

Внутренние элементы Tom Select активно используют data-атрибуты:

  • data-value — значение опции
  • data-selectable — доступность выбора
  • data-disabled — состояние блокировки

Примеры фильтрации:

document.querySelectorAll('.ts-dropdown .option[data-selectable="true"]');

или:

document.querySelectorAll('.item[data-value]');

Такой подход обеспечивает стабильную интеграцию с динамическими данными.


Селекторы для поиска и фильтрации

Поисковое поле может быть получено через комбинированные селекторы:

document.querySelector('.ts-wrapper input');

или более строго:

document.querySelector('.ts-wrapper .ts-control input[type="text"]');

Фильтрация списка осуществляется через ввод в это поле, однако DOM-селекторы позволяют отслеживать изменения:

const input = document.querySelector('.ts-wrapper input');

input.addEventListener('input', (e) => {
  const value = e.target.value;
});

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

Tom Select часто создаёт элементы после инициализации, поэтому часть селекторов становится валидной только после событий:

  • focus
  • dropdown_open
  • item_add

Пример ожидания появления dropdown:

const observer = new MutationObserver(() => {
  const dropdown = document.querySelector('.ts-dropdown');
  if (dropdown) {
    // элемент появился
  }
});

observer.observe(document.body, { childList: true, subtree: true });

Селекторы нескольких экземпляров на странице

При наличии нескольких инстансов Tom Select требуется уточнение контекста:

<select id="select-a"></select>
<select id="select-b"></select>

Изоляция селекторов:

document.querySelector('#select-a + .ts-wrapper .item');
document.querySelector('#select-b + .ts-wrapper .item');

или через контейнер:

document.querySelectorAll('.ts-wrapper').forEach(wrapper => {
  const items = wrapper.querySelectorAll('.item');
});

Селекторы кастомных шаблонов (render)

При использовании render.option и render.item создаются дополнительные DOM-узлы с пользовательскими классами:

new TomSelect('#select', {
  render: {
    option: function(data, escape) {
      return `<div class="custom-option" data-value="${data.value}">
                ${escape(data.text)}
              </div>`;
    }
  }
});

Селекторы для таких элементов:

document.querySelectorAll('.custom-option');
document.querySelector('.custom-option[data-value="x"]');

Комбинированные селекторы для сложных сценариев

Сложные интерфейсы требуют сочетания нескольких уровней:

document.querySelector(
  '.ts-wrapper:not(.disabled) .ts-dropdown .option.active'
);

или:

document.querySelectorAll(
  '.ts-wrapper .ts-dropdown .option[data-selectable="true"]:not(.disabled)'
);

Такие конструкции позволяют точно выделять элементы с заданным состоянием без дополнительной логики фильтрации в JavaScript.


Селекторы событийных состояний через классы

Некоторые состояния отражаются только в DOM:

  • открытие dropdown добавляет класс .dropdown-active
  • фокус добавляет .focus
  • загрузка данных может добавлять .loading

Пример:

document.querySelector('.ts-wrapper.dropdown-active');

или отслеживание:

document.querySelectorAll('.ts-wrapper.loading');

Практика изоляции селекторов в больших приложениях

При масштабировании интерфейсов важно избегать глобальных селекторов. Используются ограниченные области поиска:

const container = document.querySelector('#form-section');

const tomSelectItems = container.querySelectorAll('.ts-wrapper .item');

Такой подход предотвращает пересечение экземпляров и снижает риск конфликтов DOM-структуры.