Skip to content

Use the native beforeinput event if it's supported #11211

Description

@ianstormtaylor

Do you want to request a feature or report a bug?

Improvement.

What is the current behavior?

Right now, the synthetic onBeforeInput event is being created based on two other events:

  • textInput when possible—which is in Webkit.
  • keypress as a fallback.

But these days in Chrome, Safari and Opera the spec'd beforeinput event is available and actually fires. And when it does, it includes other spec'd properties which can be extremely helpful:

  • inputType tells you whether the event is inserting text, replacing text, inserting a line break, etc.
  • getTargetRanges() tells you where the input is taking place in the DOM.

Right now this information isn't exposed, because even if the browser supports beforeinput, it's not being checked for.

What is the expected behavior?

Instead React should treat textInput as a slightly-preferred fallback for native beforeinput support, but add beforeinput as the true goal. So we'd end up with a fallback stack of:

  • beforeinput
  • textInput
  • keypress

Which guarantees that the nativeEvent will always be the most spec'd and have the most relevant information associated with it.


The beforeinput event's extra properties are critical in contenteditable situations, when you want to prevent the default browser behavior from firing but perform the logic on an internal model instead. (I'm looking to do this for Slate.)

Without that extra information you have to fallback to hackier behavior—allowing the event to occur, trying to parse the DOM for what the change was, then re-rendering to remove it, etc. I want to avoid this on the more modern browsers, because it results in reduced performance.


There is another situation that this fixes, which is that spellcheck right now doesn't trigger React's onBeforeInput handler, even though modern browsers fire the beforeinput event, because it's not being listened for right now.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions