venantius / accountant

ClojureScript navigation for single-page applications, made simple.
Eclipse Public License 1.0
250 stars 39 forks source link

Cannot prevent accountant behavior on child element click #13

Closed eyelidlessness closed 8 years ago

eyelidlessness commented 8 years ago

If an a has a child tag with its own click event handling, it is not possible to prevent accountant from handling the click.

Example

(Reagent/Hiccup syntax)

[:a {:href "/whatever"}
  [:span {:onClick #(do
                     (.preventDefault %)
                     (.stopPropagation %)
                     (js/console.log "Clicked span"))} "clickme"]]

Expected result: accountant's event handler will either not receive, or disregard, the click event.

Observed result: the span's click handler is called, but accountant navigates to /whatever immediately afterwards.

eyelidlessness commented 8 years ago

Worth noting, I tried the following modifications to accountant.core/prevent-reload-on-known-path in hopes of offering a patch:

Both of these modifications proved fruitless, and suggests to me that either:

venantius commented 8 years ago

Hmmm, this is interesting, particularly in light of https://github.com/venantius/accountant/pull/12

Here are my thoughts: first, I don't understand the DOM's event model well enough myself to explain why your experiments may not have been working. Second, I'm not really sure I understand a use case for this sort of behavior that isn't an anti-pattern. What would be the expected behavior of this in the absence of any JS?

eyelidlessness commented 8 years ago

I should have followed up, I'm pretty sure the behavior is expected given how DOM events work: put simply, the first attached event is processed first (even though it is less specific). I don't think there's an appropriate way to solve this in the library context, and probably this issue should be wontfix.

In an implementation sense, the usage absolutely is an anti-pattern. I was looking for a way to easily nest clickable elements into a visually larger clickable row. Like this:

---------------------------------
| Clickable Item                 |
| [smaller] [click] [targets]    |
----------------------------------

The HTML spec specifically precludes a tags containing "interactive" children, so it shouldn't work.

Unfortunately the "correct" way to do what I was trying to achieve from a user experience perspective, while respecting basic browsing and accessibility expectations, requires some degree of hackery and chicanery (fooling with adjacent elements with special positioning, special tabindex for proper focus behavior).

venantius commented 8 years ago

Sounds like we're probably on the same page then :)