В A-Frame событие является основным механизмом взаимодействия между
компонентами и сущностями. Один из наиболее гибких способов передачи
данных при событиях — использование свойства detail. Это
объект, который можно передавать вместе с событием, обеспечивая доступ к
дополнительной информации о контексте события.
detailСобытия в A-Frame создаются через стандартный DOM-метод
emit. Синтаксис:
entity.emit(eventName, detailObject, bubbles);
eventName — строка с названием
события.detailObject — объект с произвольными
данными, передаваемыми слушателям события.bubbles — булево значение,
определяющее, будет ли событие всплывать по дереву сущностей (по
умолчанию false).Пример передачи данных через detail:
const box = document.querySelector('#box');
box.emit('customEvent', { color: 'red', speed: 2 });
Здесь событие customEvent содержит объект
{ color: 'red', speed: 2 } в detail.
detailДля обработки событий используется стандартный метод
addEventListener. Доступ к объекту detail
осуществляется через свойство события:
box.addEventListener('customEvent', (event) => {
console.log(event.detail.color); // 'red'
console.log(event.detail.speed); // 2
});
Важно отметить, что detail — это обычный объект
JavaScript, что позволяет передавать сложные структуры данных: массивы,
объекты с вложенными свойствами, функции и ссылки на сущности
A-Frame.
detail в компонентахВ компонентах A-Frame detail часто применяется для
передачи параметров между компонентами. Например, один компонент может
управлять состоянием объекта, а другой реагировать на изменения:
AFRAME.registerComponent('color-changer', {
init: function () {
this.el.addEventListener('changeColor', (e) => {
this.el.setAttribute('material', 'color', e.detail.color);
});
}
});
AFRAME.registerComponent('color-controller', {
play: function () {
const el = this.el;
setTimeout(() => {
el.emit('changeColor', { color: 'blue' });
}, 1000);
}
});
В этом примере компонент color-controller инициирует
событие с передачей цвета, а color-changer применяет этот
цвет к материалу сущности.
Объект detail поддерживает любые типы данных, включая
массивы и вложенные объекты:
const sceneEl = document.querySelector('a-scene');
sceneEl.emit('updateInventory', {
items: [
{ name: 'sword', damage: 10 },
{ name: 'shield', defense: 5 }
],
gold: 250
});
Обработчик может получить доступ к каждому элементу:
sceneEl.addEventListener('updateInventory', (event) => {
console.log(event.detail.items[0].name); // 'sword'
console.log(event.detail.gold); // 250
});
Такая структура позволяет передавать комплексные данные между системами и компонентами, избегая глобальных переменных и прямой зависимости между объектами сцены.
detailСобытия в A-Frame по умолчанию не всплывают. Если необходимо, чтобы
событие передавалось вверх по дереву сущностей, нужно установить
bubbles: true:
box.emit('customEvent', { key: 'value' }, true);
Слушатели на родительских сущностях смогут получить объект
detail:
const parent = document.querySelector('#parent');
parent.addEventListener('customEvent', (e) => {
console.log(e.detail.key); // 'value'
});
Это позволяет создавать иерархические взаимодействия между сущностями, сохраняя чистоту архитектуры.
detaildetail для передачи состояния и
параметров, а не для постоянного хранения данных.detail, чтобы
избежать ошибок доступа к неопределённым свойствам.box.emit('startAnimation', { duration: 2000, easing: 'easeInOutQuad' });
player.emit('pickupItem', { id: 42, name: 'Magic Wand' });
uiPanel.emit('menuClosed', { timestamp: Date.now() });
detail обеспечивает универсальный и гибкий способ
передачи информации внутри сцены A-Frame, минимизируя жёсткие связи
между компонентами и облегчая масштабирование интерактивного
контента.