Остановка распространения

В PixiJS событийная система построена на концепции пузырькового распространения событий (event bubbling), аналогичной DOM. Когда происходит событие, например pointerdown или click, оно сначала обрабатывается на целевом объекте, а затем поднимается вверх по иерархии контейнеров до корня сцены, если не было прервано. Контроль этого поведения осуществляется с помощью методов и свойств событий.

Свойство stopPropagation()

Каждое событие, передаваемое обработчику, представляет собой объект PIXI.InteractionEvent, который содержит свойство stopPropagation(). Вызов этого метода предотвращает дальнейшее распространение события по иерархии родителей.

Пример:

const button = new PIXI.Sprite.from('button.png');
button.interactive = true;

button.on('pointerdown', (event) => {
    console.log('Событие на кнопке');
    event.stopPropagation();
});

const container = new PIXI.Container();
container.addChild(button);

container.on('pointerdown', () => {
    console.log('Событие на контейнере');
});

В этом примере при клике на button сообщение «Событие на контейнере» не появится, потому что stopPropagation() останавливает распространение события к родительскому контейнеру.

Различие между stopPropagation() и stopImmediatePropagation()

Помимо stopPropagation(), существует метод stopImmediatePropagation(). Он отличается тем, что не только останавливает распространение вверх по иерархии, но и прекращает вызов остальных обработчиков на текущем объекте. Это важно, если на одном объекте зарегистрировано несколько обработчиков одного типа события.

button.on('pointerdown', () => console.log('Первый обработчик'));
button.on('pointerdown', (event) => {
    console.log('Второй обработчик и остановка');
    event.stopImmediatePropagation();
});
button.on('pointerdown', () => console.log('Третий обработчик'));

При клике будет выведено только:

Первый обработчик
Второй обработчик и остановка

Третий обработчик вызван не будет.

Влияние interactiveChildren на распространение

Свойство interactiveChildren у контейнеров управляет тем, могут ли дочерние объекты получать события. Если interactiveChildren = false, события не доходят до потомков, и они могут быть обработаны только самим контейнером. Это создаёт дополнительный уровень контроля над распространением.

const container = new PIXI.Container();
container.interactiveChildren = false;

const sprite = new PIXI.Sprite.from('sprite.png');
sprite.interactive = true;

container.addChild(sprite);

sprite.on('pointerdown', () => console.log('Это событие не сработает'));
container.on('pointerdown', () => console.log('Сработает контейнер'));

Практическое применение

  1. Кнопки и интерфейсные элементы Часто кнопки расположены на фоне, реагирующем на события. Использование stopPropagation() предотвращает случайное срабатывание фонового обработчика.

  2. Дерево объектов В сложных сценах с вложенными контейнерами остановка распространения позволяет разделять логику обработки событий для разных слоев.

  3. Групповая обработка Иногда событие нужно обработать только один раз на самом верхнем уровне и не допускать его дальнейшего всплытия. stopImmediatePropagation() помогает гарантировать, что никакие другие обработчики не вмешаются.

Особенности поведения

  • События pointer* (например, pointerdown, pointerup) распространяются по цепочке контейнеров, пока не будет вызван stopPropagation().
  • События мыши mousedown, mouseup работают аналогично, но для них важно, чтобы объект имел interactive = true.
  • Контейнеры и спрайты обрабатываются одинаково, разница только в наличии потомков и interactiveChildren.

Резюме по методам

Метод Действие
stopPropagation() Останавливает распространение события вверх по иерархии
stopImmediatePropagation() Останавливает распространение и предотвращает вызов других обработчиков на текущем объекте

Эти инструменты дают полный контроль над потоками событий в сцене PixiJS, позволяя создавать сложные интерфейсы и интерактивные сцены без конфликта между элементами.