+ 1 для обоих остальных ответов. События являются лучшими, потому что тогда Компоненты слабо связаны
Обратите внимание, что в detail
пользовательского события вы можете отправлять все, что захотите.
Выполнение управляемой событиями функции:
Поэтому я использую (код псевдо):
Элементы, определяющие игру пасьянс / свободная ячейка:
-> game Element
-> pile Element
-> slot Element
-> card element
-> pile Element
-> slot Element
-> empty
Когда карта (перетаскиваемаяпользователь) должен быть перемещен в другую кучу,
он посылает Событие (поднимая DOM к игровому элементу)
//triggered by .dragend Event
card.say(___FINDSLOT___, {
id,
reply: slot => card.move(slot)
});
Примечание: reply
является функцией определение
Потому что все свай, где сказано слушать ___FINDSLOT___
События в элементе игры ...
pile.on(game, ___FINDSLOT___, evt => {
let foundslot = pile.free(evt.detail.id);
if (foundslot.length) evt.detail.reply(foundslot[0]);
});
Отвечает только одна куча, соответствующая evt.detail.id
:
!!! выполняя функцию card
, отправленную в evt.detail.reply
И получая техническую информацию: функция выполняется в pile
scope!
(приведенный выше код является псевдокодом! )
Почему?!
Может показаться сложным;
Важная часть заключается в том, что элемент pile
НЕ связан к методу .move()
в элементе card
.
Связь only - это имя события: ___FINDSLOT___
!!!
Это означает, что card
всегда находится под контролем, и одно и то же событие (имя) может использоваться для:
- Куда может пойти карта?
- Какое лучшее место?
- Какая карта на реке 1079 *
pile
делает фулл-хаус? - ...
В моем электронном коде pile
тоже не связан с evt.detail.id
,
Пользовательские события отправляют только функции
.say()
и .on()
- мои собственные методы (для каждого элемента) для dispatchEvent
и addEventListener
I nу нас есть набор электронных элементов, которые можно использовать для создания любой карточной игры
.. появится на GitHub позже в этом месяце
sneak peek:
Нет необходимостилюбые библиотеки, напишите свой собственный 'Message Bus'
Мой метод element.on()
- это всего лишь несколько строк кода, обернутых вокруг функции addEventListener
, поэтому их можно легко удалить:
$Element_addEventListener(
name,
func,
options = {}
) {
let BigBrotherFunc = evt => { // wrap every Listener function
if (evt.detail && evt.detail.reply) {
el.warn(`can catch ALL replies '${evt.type}' here`, evt);
}
func(evt);
}
el.addEventListener(name, BigBrotherFunc, options);
return [name, () => el.removeEventListener(name, BigBrotherFunc)];
},
on(
//!! no parameter defintions, because function uses ...arguments
) {
let args = [...arguments]; // get arguments array
let target = el; // default target is current element
if (args[0] instanceof HTMLElement) target = args.shift(); // if first element is another element, take it out the args array
args[0] = ___eventName(args[0]) || args[0]; // proces eventNR
$Element_ListenersArray.push(target.$Element_addEventListener(...args));
},
.say( )
является абонентом:
say(
eventNR,
detail, //todo some default something here ??
options = {
detail,
bubbles: 1, // event bubbles UP the DOM
composed: 1, // !!! required so Event bubbles through the shadowDOM boundaries
}
) {
el.dispatchEvent(new CustomEvent(___eventName(eventNR) || eventNR, options));
},
Danny.say(
__NATIVE_ELEMENTS_LOVERS__,
() => mail('danny@engelman.nl' , 'Re: early access to your E-lements GitHub')
);