Работа с коллекциями элементов

Umbrella JS предоставляет лёгкий интерфейс для манипуляции наборами DOM-элементов. Основой является объект-коллекция, который формируется вызовом u(selector) и ведёт себя подобно массиву: содержит элементы в порядке выборки и поддерживает итерирование. В отличие от массива, коллекция обогащена методами для работы c DOM и событиями.

Формирование коллекций

Выборка элементов осуществляется по CSS-селектору либо путём передачи готового DOM-узла или массива узлов:

u('li.selected')
u(document.body)
u([el1, el2, el3])

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

Особенности неизменяемости выборки

Коллекция не реагирует на последующие изменения DOM-дерева автоматически. Добавление новых элементов в документ не включается в ранее сформированную выборку. Для получения актуального набора требуется новое обращение u(selector).

Итерация и преобразование

Метод each

Для последовательной обработки используется each(callback). Коллбэк вызывается для каждого элемента коллекции, ему передаются сам элемент и его индекс:

u('input').each(function(el, i) {
  el.value = el.value.trim();
});

each не формирует новую коллекцию, а возвращает исходную, позволяя строить цепочки вызовов.

Метод map

Преобразование коллекции в массив значений выполняется через map(callback):

const ids = u('li').map(function(el){ return el.id; });

Результат — обычный массив. Это удобно для вычислений, сериализации или взаимодействия с внешними API.

Метод filter

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

const visible = u('div').filter(function(el){
  return el.offsetParent !== null;
});

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

Манипуляции с содержимым

Текст и HTML

Коллекции поддерживают методы text() и html(). При вызове без аргументов возвращается содержимое первого элемента. Передача строки изменяет содержимое всех элементов:

u('p.note').text('Обновлено');
u('#content').html('<span>Готово</span>');

Вставка фрагментов производится через append, prepend, before и after. Эти методы принимают строку или DOM-узел и распространяют операцию на каждый элемент коллекции, создавая дубликаты по необходимости.

Атрибуты и свойства

attr(name) возвращает значение атрибута первого элемента. Передача пары name, value устанавливает атрибут всем элементам. Аналогично работают addClass, removeClass, toggleClass для управления классами и css для стилей.

u('img').attr('alt', 'Фото');
u('.box').css({ width: '200px', height: '100px' });

Манипулирование структурой DOM

Вставка и перемещение

Методы appendTo(selector) и prependTo(selector) перемещают элементы текущей коллекции к целевой. При этом реальные узлы перемещаются в DOM, а не клонируются, что важно учитывать при повторном использовании ссылок на узлы.

Клонирование

Для дублирования узлов применяется clone(). Возвращается новая коллекция с клонами всех элементов, пригодная для последующей вставки в любое место DOM.

Работа с событиями

Привязка обработчиков

on(event, handler) навешивает обработчик на каждый элемент коллекции. Для удаления используется off. Поддерживается делегирование: если указать селектор вторым аргументом, обработчик будет вызываться только при совпадении цели события:

u('#list').on('click', 'li', function(e){
  u(this).toggleClass('selected');
});

Инициирование событий

trigger(eventName) позволяет искусственно инициировать событие для всех элементов выборки. Это полезно при тестировании и для синхронизации пользовательских сценариев.

Трансформации коллекций

Объединение и пересечение

Для объединения используется add(selectorOrNodes), возвращающий новую коллекцию, содержащую текущие элементы и элементы аргумента. Пересечение обеспечивается filter, который часто применяют совместно с селектором:

const active = u('li').filter('.active');

Получение подмножеств

first(), last() и eq(index) извлекают подмножества как новые коллекции. Такие методы удобны при точечной модификации конкретных элементов внутри цепочки.

Связь с формами и данными

Значения элементов форм

val() без аргумента возвращает значение первого элемента формы. При передаче значения обновляются все элементы:

u('input[name="q"]').val('поиск');

Для чекбоксов и радиокнопок учитывается состояние checked, а для списков — выбранный пункт.

Сериализация

serialize() формирует строку URL-кодированных параметров на основе полей форм в коллекции. Используется при отправке данных через fetch или XMLHttpRequest.

Производительность и особенности цепочек

Методы Umbrella JS традиционно возвращают коллекцию, обеспечивая стиль fluent-API. Это уменьшает количество промежуточных переменных и упрощает чтение кода. При работе с большими коллекциями рекомендуется комбинировать filter и each, чтобы ограничить объём операций. Браузерные reflow и repaint лучше минимизировать за счёт группировки операций вставки и изменения стилей.

Интеграция с нативным DOM и другими библиотеками

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

const list = u('li').nodes;

Парадигма Umbrella JS строится на принципе минимального покрытия: поддерживаются только наиболее востребованные операции, а расширение функциональности предлагается за счёт нативных средств JavaScript и стандартного API DOM.