Метод selectAll()

Метод selectAll() библиотеки Snap.svg используется для выборки набора SVG-элементов по CSS-селектору. В отличие от метода select(), который возвращает только первый найденный элемент, selectAll() формирует коллекцию всех совпадающих узлов, что позволяет выполнять групповые операции.

Результатом работы метода является объект типа Snap.set — специальная коллекция, содержащая элементы Snap.svg и предоставляющая удобные методы для их обработки.


Синтаксис

Snap.selectAll(selector)

или

paper.selectAll(selector)

Параметры:

  • selector — строка CSS-селектора (например: "circle", ".className", "#id")

Возвращаемое значение:

  • Объект Snap.set, содержащий найденные элементы

Принцип работы

Метод выполняет поиск элементов внутри SVG-документа, используя стандартные CSS-селекторы. Поиск может выполняться:

  • глобально через Snap.selectAll()
  • в пределах конкретного SVG-контекста через paper.selectAll()

Каждый найденный элемент оборачивается в объект Snap, после чего добавляется в коллекцию Snap.set.


Простейший пример

var s = Snap("#svg");

var circles = s.selectAll("circle");

circles.forEach(function(el) {
    el.attr({ fill: "red" });
});

Что происходит:

  • выбираются все <circle> внутри SVG
  • каждому элементу устанавливается красный цвет заливки

Работа с классами

var elements = Snap.selectAll(".highlight");

elements.attr({
    stroke: "blue",
    strokeWidth: 2
});

Метод attr() можно применять ко всему набору сразу — это одно из ключевых преимуществ Snap.set.


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

selectAll() поддерживает любые валидные CSS-селекторы:

var items = Snap.selectAll("rect.active, circle.big");

items.forEach(function(el) {
    el.attr({ opacity: 0.5 });
});

Возможности:

  • выборка по нескольким типам элементов
  • комбинирование классов
  • вложенные селекторы

Объект Snap.set

Результат работы selectAll() — это не обычный массив, а специализированный объект:

var set = Snap.selectAll("path");

Особенности Snap.set:

  • хранит список элементов

  • поддерживает методы:

    • attr()
    • animate()
    • forEach()
    • push()
    • exclude()
    • remove()

Пример массовой анимации

var shapes = Snap.selectAll("rect");

shapes.animate({ transform: "r45" }, 1000);

Все прямоугольники одновременно поворачиваются на 45 градусов.


Итерация по элементам

var lines = Snap.selectAll("line");

lines.forEach(function(el, index) {
    el.attr({ stroke: index % 2 === 0 ? "black" : "gray" });
});

Параметры callback:

  • el — текущий элемент
  • index — индекс в наборе

Добавление элементов в набор

var set = Snap.selectAll("circle");

var newCircle = Snap("#svg").circle(50, 50, 20);

set.push(newCircle);

Позволяет динамически расширять коллекцию.


Удаление элементов

var elements = Snap.selectAll(".temp");

elements.remove();

Все элементы с классом .temp удаляются из SVG.


Ограничение области поиска

var group = Snap("#group1");

var elements = group.selectAll("rect");

Поиск выполняется только внутри указанной группы.


Сравнение с select()

Метод Возвращает Количество элементов
select() Один элемент Первый найденный
selectAll() Snap.set Все совпадения

Особенности и нюансы

1. Пустой результат

Если элементы не найдены:

var items = Snap.selectAll(".unknown");

items будет пустым Snap.set, а не null.


2. Производительность

При большом количестве элементов:

  • массовые операции через attr() быстрее, чем forEach()
  • сложные селекторы могут замедлять поиск

3. Живой или статический набор

Snap.set не является “живым” списком:

var set = Snap.selectAll("circle");

// добавление нового круга позже
s.circle(10, 10, 5);

// set НЕ обновится автоматически

Для получения актуального списка требуется повторный вызов selectAll().


Практический пример: подсветка элементов при наведении

var items = Snap.selectAll("rect");

items.forEach(function(el) {
    el.hover(
        function() {
            el.attr({ fill: "orange" });
        },
        function() {
            el.attr({ fill: "blue" });
        }
    );
});

Комбинирование с анимацией

var circles = Snap.selectAll("circle");

circles.forEach(function(el, i) {
    el.animate(
        { cy: el.attr("cy") + 50 },
        500 + i * 100
    );
});

Создаётся эффект “волны” за счёт задержки.


Использование с фильтрацией

var shapes = Snap.selectAll("rect");

var large = new Snap.set();

shapes.forEach(function(el) {
    if (el.attr("width") > 100) {
        large.push(el);
    }
});

large.attr({ fill: "green" });

Ошибки и распространённые проблемы

Неверный селектор

Snap.selectAll("circl"); // ошибка — элемент не найден

Попытка использовать методы DOM

var set = Snap.selectAll("rect");

set.style.fill = "red"; // не работает

Следует использовать attr().


Забытый контекст

Snap.selectAll("rect");

Ищет по всему документу, а не в конкретном SVG.


Итоговое понимание

Метод selectAll() является ключевым инструментом для работы с множеством SVG-элементов в Snap.svg. Он позволяет:

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

Глубокое понимание Snap.set и работы селекторов открывает возможности для создания динамичных и оптимизированных SVG-интерфейсов.