Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

blur and change events fire for elements removed from DOM #3847

Closed
Jemt opened this issue Jul 24, 2018 · 7 comments · Fixed by #8392
Closed

blur and change events fire for elements removed from DOM #3847

Jemt opened this issue Jul 24, 2018 · 7 comments · Fixed by #8392
Labels
interop Implementations are not interoperable with each other topic: focus

Comments

@Jemt
Copy link

Jemt commented Jul 24, 2018

Chrome strictly follows the specs described here:
https://html.spec.whatwg.org/multipage/interaction.html#focus-fixup-rule
https://html.spec.whatwg.org/multipage/interaction.html#unfocusing-steps

This has resulted in the following bug:
https://bugs.chromium.org/p/chromium/issues/detail?id=866242

Disposing a DOM element may - without clarification in the spec - result in OnChange and OnBlur firing for DOM elements that has been disposed. In most cases that does not make sense, and it has great potential to cause unforeseen problems in web applications, e.g. those built on libraries/frameworks that actually tries to manage memory well (React , Fit.UI , etc.).

Firefox, Safari/Webkit, and MS Edge behaves as expected - they do not invoke event handlers for disposed objects, but Google will not fix the bug unless the spec describes the expected behaviour in the situation described above.

@annevk
Copy link
Member

annevk commented Jul 26, 2018

Does disposed mean anything more than element.remove()?

@Jemt
Copy link
Author

Jemt commented Jul 26, 2018

Yes, all it means is that the element has been removed from DOM.

@domenic domenic added the interop Implementations are not interoperable with each other label Sep 24, 2019
@FlowIT-JIT
Copy link

Any progress or decision on this issue ?

@lpd-au
Copy link

lpd-au commented Jun 6, 2021

In his response to the Chrome issue linked in the description, @tkent-google pointed to the focus fixup rule and unfocusing steps to show that the focusing steps and focus update steps are called and therefore blur and change events are triggered. Both then and now, I understand that the unfocusing steps short circuit before performing any meaningful work (then at steps 5 and 6, now at step 5), so we can concentrate solely on the focus fixup rule.

The focus fixup rule currently says, unchanged from then:

Focus fixup rule: When the designated focused area of the document is removed from that Document in some way (e.g. it stops being a focusable area, it is removed from the DOM, it becomes expressly inert, etc.), designate the Document's viewport to be the new focused area of the document.

Does "designate focusable area x to be the new focused area of the document" imply that the focusing steps should be run? It's a little ambiguous. If it did, I believe the focus update steps would become recursive from step 4.1:

If entry is a focusable area: designate entry as the focused area of the document.

The focusing steps themselves state that they should be run "whenever the user attempts to move the focus", which wouldn't cover an element being removed from the document.

To address this as well as other ambiguity I perceive to exist in the rule, last week I filed #6729. I only came across this issue today while doing further research on the topic, but depending on how implementers view these points, it may be that your preferred behaviour is already the more accepted reading of the current spec.

@domenic
Copy link
Member

domenic commented Jan 19, 2022

I tend to agree with @lpd-au's reading. However it is not straightforward, as for example the sentence

When the currently focused area of a top-level browsing context is somehow unfocused without another element being explicitly focused in its stead, the user agent must immediately run the unfocusing steps for that object.

if taken literally would apply to the focus fixup rule, because the focus fixup rule will focus the viewport, which is not an element. (And, it "designates" instead of "focuses" the viewport...)

We should fix this and #6729 at the same time.

Note that we have pretty exhaustive tests for the focus fixup rule in https://github.com/web-platform-tests/wpt/blob/master/html/interaction/focus/processing-model/focus-fixup-rule-one-no-dialogs.html , which only Chromium passes. (Other browsers may do focus fixup async, I believe.) But as @lpd-au points out in web-platform-tests/wpt#29258 we do not have tests for blur (or focus) events in such cases.

I will add this to the next HTML triage meeting for discussion. /cc @mfreed7 @josepharhar since Chromium is the odd one out. My weak preference would be to align with Chromium on performing the focus fixup rule synchronously, but with Gecko and WebKit on not firing the events, but I haven't thought through the compat implications too much. It may be the case this is causing compat problems for Gecko and WebKit in which case aligning on the Chromium behavior would be necessary.

@domenic domenic added the agenda+ To be discussed at a triage meeting label Jan 19, 2022
@whatwg whatwg deleted a comment Jan 19, 2022
@annevk annevk changed the title OnBlur and OnChange fires for objects removed from DOM (disposed) blur and change events fire for elements removed from DOM Jan 26, 2022
@past past removed the agenda+ To be discussed at a triage meeting label Feb 3, 2022
@vincerubinetti
Copy link

vincerubinetti commented Mar 2, 2022

Just my two cents as an average joe developer. I would not expect an onchange event to be fired when a DOM element is removed, intuitively.

MDN says the following:

The change event is fired ... when an alteration to the element's value is committed by the user.

Key words in bold. A value has been "committed", or decided upon, by the user. Deletion would not fall under that interpretation. And yes I know MDN is not an official authority, but in this case I think it reflects what most developers would intuitively expect; what they imagine the purpose of onchange to be.

I filed this issue in Chromium recently when this behavior cost me several hours of troubleshooting/head scratching:
https://bugs.chromium.org/p/chromium/issues/detail?id=1297334

@emilio
Copy link
Contributor

emilio commented Apr 7, 2022

There is another case here which is when the element is disconnected / moves in the shadow tree. See https://bugzilla.mozilla.org/show_bug.cgi?id=1551621 for something related to that.

domenic added a commit that referenced this issue Oct 16, 2022
* Split it into two variants: one which runs synchronously on HTML element removal, and one which runs during "update the rendering". Closes #8225.

* Be clear that the fixup does not cause any of the normal focus algorithms to run, and thus blur and change events do not fire. Also, delete the confusing "somehow unfocused without another element being explicitly focused" sentence. Fixes #3847. Fixes #6729.
domenic added a commit that referenced this issue Nov 4, 2022
* Split it into two variants: one which runs synchronously on HTML element removal, and one which runs during "update the rendering". Closes #8225.

* After this split, only the "update the rendering" variant causes the normal focus algorithms to run, and thus blur and change events to fire.

* Delete the confusing "somehow unfocused without another element being explicitly focused" sentence.

Fixes #3847. Fixes #6729.
domenic added a commit that referenced this issue Jan 18, 2023
* Split it into two variants: one which runs synchronously on HTML element removal, and one which runs during "update the rendering". Closes #8225.

* After this split, only the "update the rendering" variant causes the normal focus algorithms to run, and thus blur and change events to fire.

* Delete the confusing "somehow unfocused without another element being explicitly focused" sentence.

Fixes #3847. Fixes #6729.
@whatwg whatwg deleted a comment Jan 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interop Implementations are not interoperable with each other topic: focus
Development

Successfully merging a pull request may close this issue.

8 participants