whatwg/html

<details> 'toggle' simple event bubbling

jammnrose opened this issue · 17 comments

Currently, the spec states that whenever the open attribute is changed on the <details> element, a simple event named toggle will be fired on it.

https://html.spec.whatwg.org/multipage/forms.html#the-details-element:fire-a-simple-event

Fire a simple event named toggle at the details element.

I couldn't find anywhere that stated the toggle event should bubble, but it would make sense (to me) that this event should bubble.

Does it in implementations?

I've only tested in stable Firefox and Chrome. In Firefox 47 the details element needs to be enabled in about:config, see: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details#Browser_compatibility (v48+ it's enabled by default). In v47 which I tested with though, it seems like support for the element is still half baked and the toggle event doesn't fire at all (even on the element).
In the latest stable Chrome, the event fires only on the element and does not bubble, as specified by the spec (or by lack of additional specification that it should bubble).

The specification is quite clear in that it shouldn't bubble. However, if it's more useful for developers if it does, perhaps we should reconsider.

@aethanyc @tkent-google thoughts?

The specification is quite clear in that it shouldn't bubble.

Yep, it certainly is, and it's not at all surprising to me that Chrome implemented it to-spec.

As a developer, I do think it would make sense and be more useful for this event to bubble so delegated event handlers can be used. There are ways around this in lieu of this event not bubbling, but it would make much more sense to me if the event bubbled.

Firefox implemented the toggle events in Bug 1225412 which is in Firefox 48. Firefox certainly does follow the spec, but I see no reason that the toggle event cannot bubble. And it should be trivial to implement the bubbling.

@smaug---- any concerns?

Well, if you have nested <detail>s and they have ontoggle and one toggles the deepest <details>, the handlers on ancestor <detail>s fire rather unexpectedly.
So I wouldn't change the event to bubble, given the <detail> has shipped in certain browsers for quite some time. At least I wouldn't change the behavior without some data about the use of nested <detail>s.

And if one needs to listen for toggle at higher level, use capturing listeners.

Fair, I'm going to close this then. It can be reopened if WebKit/Chromium are comfortable changing their behavior, which seems unlikely.

The point about nested details is a good one, and fatal to the idea of bubbling IMO. Thanks @smaug---- for catching that.

The point about nested details is a good one, and fatal to the idea of bubbling IMO.

To play devil's advocate, wouldn't that argument be equally valid with respect to bubbling "click"? The Event interface has target for just this purpose.

If you click on something inside something else, it's arguable that you clicked on the outer thing too. (I.e., not only did I click on the button, I also clicked on the document; both are true, and both objects should be notified of the click.) Whereas if you toggle a details inside another details, you definitely didn't toggle the outer details.

What about "dragstart"/"dragend" (since I didn't start/stop dragging the ancestor) or "submit" (since it's forms that get submitted, not their ancestors)? Bubbling can be very useful, and should not be discarded so lightly.

Forms cannot be nested. I'm not sure about the drag event handlers; maybe they should not bubble either, but presumably IE8 or whatever made them bubble and everyone else followed them, so no need to change that now.

75lb commented

I have a long list of details elements. Each details item in the list represents a Github repository which can be expanded to show further stats, graphs and info.

<repository-list>
  <details><summary>Repository A</summary></details>
  <details><summary>Repository B</summary></details>
  <details><summary>Repository C</summary></details>
  <details><summary>Repository D</summary></details>
  <details><summary>Repository E</summary></details>
  <details><summary>Repository F</summary></details>
  <details><summary>Repository G</summary></details>
  ...etc
</repository-list>

I want to lazy-load the repository data on toggle of the details item. However, the lack of toggle event bubbling forces me to attach an event listener to every details in the list (up to 1000 in this case). This feels inefficient and wrong, I want to attach one event listener to repository-list and operate on e.target (the same way we'd do it when handling click events at ul level on long li lists).

The argument about nested details elements does not apply in this case.

Can't you add capturing event listener on repository-list?

75lb commented

@smaug----

I can listen for toggle on repository-list but nothing will bubble up to it as the toggle event does not bubble - that is the subject of this issue report. This issue forces me to create thousands of event listeners (one per details element) where normally one at the level above would suffice.

Use capturing, not bubbling.

75lb commented

tsk, i forgot about capture mode.. thanks guys 👍