Skip to content
Advertisement

Should the HTML element dispatch `beforeinput` events?

The MDN page for beforeinput states that:

The DOM beforeinput event fires when the value of an <input>, <select>, or <textarea> element is about to be modified

<select> is clearly mentioned as supporting the beforeinput event.

This also seems to be true based on my simple reading of the spec:

Trusted Targets: Element (specifically: control types such as HTMLInputElement, etc.) or any Element with contenteditable attribute enabled

(emphasis mine)

However, no browser seems to implement it. I have checked Chrome, Safari and Firefox.

Am I understanding something incorrectly?

const sel = document.getElementById('pet-select')
sel.addEventListener('beforeinput', () => console.log('beforeinput!'))
sel.addEventListener('input', () => console.log('input!'))
<label for="pet-select">Choose a pet:</label>

<select name="pets" id="pet-select">
    <option value="">--Please choose an option--</option>
    <option value="dog">Dog</option>
    <option value="cat">Cat</option>
    <option value="hamster">Hamster</option>
    <option value="parrot">Parrot</option>
    <option value="spider">Spider</option>
    <option value="goldfish">Goldfish</option>
</select>

Advertisement

Answer

The MDN page copied its summary from the input event page, which does indeed fire on this element. I did open a PR there to rectify this.

The beforeinput event isn’t supposed to fire on <select>, just like it doesn’t fire on non textual inputs:

addEventListener('input', () => console.log('input!'))
addEventListener('beforeinput', () => console.log('beforeinput!'))
<input type=text placeholder="here it fires"><br>
<input type=checkbox><br>
<input type=radio><br>
<input type=file><br>
<input type=color>

To understand that, we need to go back in History and see how the input event was first designed by the HTML’s specs.
It’s only after some times that it got moved to the W3C/UI-Events working group.
The beforeinput one on the other hand was drafted by the W3C/Editing group and then transferred to the W3C/UI-Events.

The discussions in the W3C/UI-Events group make it clear that their intent was for it to fire only for changes that came from user keyboard inputs. They even initially expected it to NOT fire for actions such as paste or cut.


Ok, but why does the input event fires on <select> and other non textual input elements?

That’s because the HTML specs (now handled by WHATWG) actually still do define the input event and ask for it to happen:

For the <select> element they say:

When the user agent is to send select update notifications, queue an element task on the user interaction task source given the select element to run these steps:

  1. Fire an event named input at the select element, with the bubbles and composed attributes initialized to true.

As for textual <input> they say:

When the input and change events apply (which is the case for all input controls other than buttons and those with the type attribute in the Hidden state), the events are fired to indicate that the user has interacted with the control. The input event fires whenever the user has modified the data of the control.

And for checkboxes:, radio, and file inputs you’ll find something along these lines:

The input activation behavior is to run the following steps:

  1. If the element is not connected, then return.

  2. Fire an event named input at the element with the bubbles and composed attributes initialized to true.

  3. Fire an event named change at the element with the bubbles attribute initialized to true.


The only mention to the beforeinput event in the HTML specs has been added only 11 days ago, but that PR only exposes the event globally, it doesn’t change its definition.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement