Order of EventListeners

by Danny Engelman

HTML

<h3>Custom Element EventListeners (see console)</h3>
<my-element id=ONE><button>Event from DOM Element</button></my-element>
<my-element id=TWO shadowDOM="true"></my-element>

<script>
  const _EVENT = "my-event";
  const _ELEMENT = "my-element";
  const _EVENTBUS = document; // all Events communicate via this SHARED! parent Element

  const _EVENTBUSHandler = (evt, receiver = 'catchall') => {
    console.log(`%c Receiver: `, 'background:lightgreen', receiver)
    let sender = evt.detail.sender; //or extract from composedPath
    if (sender === receiver) {
      //received the event I sent
    } else {
      let target = evt.target; // can't see origins INSIDE shadowRoots
      let composed = evt.composedPath(); // complete DOM path including shadowRoots
      target != sender && console.warn('This Event came from (deep) inside shadowDOM', target);
      console.log('sender:', sender, '\ntarget', target, '\ncomposedPath', composed, '\nevent Object:', {
        evt
      });
      evt.detail.confirm(receiver); // tell the sender we received the Event
    }
    console.log('--- end Receiver');
  }

  _EVENTBUS.addEventListener(_EVENT, _EVENTBUSHandler);// CatchAll _EVENT events, not required

  customElements.define(_ELEMENT, class extends HTMLElement {
    connectedCallback() {
      if (this.hasAttribute("shadowDOM")) this.attachShadow({
          mode: 'open'
        }).innerHTML = `<button>Event from shadowDOM Element</button>` +
        `<my-element id=THREE><button>Event from INSIDE shadowDOM Element</button></my-element>`;

      let dispatchFrom = this.shadowRoot || this;// with or without shadowDOM
      let dispatch = evt => dispatchFrom.dispatchEvent(new CustomEvent(_EVENT, {
        bubbles: true,
        composed: true, // to make event escape shadowDOM
        detail: {
          message: this.id,
          sender: this, // extra payload pointer  because Event will not see THREE inside shadowDOM
          confirm: (receiver) => {
          	//sender...