Stimulus Discourse

Event delegation order

I have a setup where there is a custom behavior attached to a container, say, list. I add a mousedown event listener to the container to capture an interaction which does a “reorder in place”. This is done using addEventListener on the container. The container in turn contains elements inside of which multiple buttons / widgets controlled by Stimulus are present. So the structure is roughly this:

<div class="list"> 
  <div class="list-item"><!-- this item become draggable=true after the mousedown behavior on "list" completes -->
      <a href="..." data-controller="magic_widget" data-action=""mousedown->magic_widget#activate">
         ...
      </a>
  </div>
</div>

The mousedown handler on “list” is configured in such a way that it will look for closest with the class of “list” and will engage the reorderable behavior only if one is found. The odd thing is that the “mousedown” action on the anchor element in this case is not detected. So it seems as if the Stimulus event listener is installed on, say, document and the event is not bubbling from the element, but instead is handled after it reaches the listener on “list”.

Is there anything peculiar I should be aware of regarding where event listeners are added in Stimulus for the actions?

Hey @julik!

This doesn’t sound like anything Stimulus specific, it handles listeners just as you’d expect vanilla JS to.

Can you share some more of your code, such as the event listener on List? It’s possible it’s swallowing the event somehow.

A few questions:

  1. Is the JS on the list container not handled via a Stimulus controller? (not that it should matter, just curious)
  2. If you remove the event listener from list, does the mouse down event on anchor trigger as expected?
  3. Are you setting any options on your event listener or just the event name and function?
  4. Is the Stimulus controller actually participating in the reordering process or is that all handled on the list? (just curious, not likely related)

Can you share an example somewhere?

Hi @thijs :slight_smile: I’ll have a second look on which event handlers I have attached in more detail and post the structure here.

@welearnednothing

  1. Is the JS on the list container not handled via a Stimulus controller? (not that it should matter, just curious)

No, it isn’t - it is separately attached imperatively.

  1. If you remove the event listener from list , does the mouse down event on anchor trigger as expected?

That I need to investigate. It seems there is a tricky drag-and-drop dropzone DOM element which is overlaying the element on which I attach the Stimulus action - I suspect that is more likely the issue (so it is a hit test problem, not an event delegation issue)

  1. Are you setting any options on your event listener or just the event name and function?

No options, just the event name and function - so no bubble reconfiguration and no capture.

  1. Is the Stimulus controller actually participating in the reordering process or is that all handled on the list? (just curious, not likely related)

The Stimulus controller not receiving the mousedown is not participating in the reorder

I haven’t tried to duplicate the issue but I noticed som oddities on your action element:

<a data-action=""mousedown->magic_widget#activate">

Stimulus controller identifiers uses kebab case where you are using an underscore notation. Also, you have an extra double quote at the beginning of your data-action value. Maybe fixing those issues will resolve it:

<a data-action="mousedown->magic-widget#activate">