Basics

input vs change event — and why your search only fires after clicking away

Illustration: two bells on a desk by a blank form — the small one rings nonstop, the big one waits until you're done

You're building search-as-you-type. Someone types "sneakers" — and the results don't change. They keep typing. Nothing. Then they click somewhere outside the field — and the results finally appear.

The code works, technically. You just hooked the handler to the change event. And it fires not when the text changes, but when the person has finished changing it. For search you needed input.

Let's break down how they differ and when to use which.

In short: the difference

  • input fires on every change to the value. Every letter, every delete, every paste.
  • change fires when the change is committed. For a text field that's usually when it loses focus. In most browsers, also on Enter.

Analogy: input is a friend reading over your shoulder while you write. change is the one who waits until you hand over the finished page.

Both are regular browser events, part of the DOM. You subscribe the same way:

field.addEventListener("input", (e) => search(e.target.value))
field.addEventListener("change", (e) => save(e.target.value))

Comparison by form field

How change behaves depends on the field type. That's the main source of confusion:

  • Text, textarea. input — on every letter. change — when you leave the field (or press Enter). If the text is put back to what it was, change doesn't fire at all.
  • Checkbox, radio button. Both fire immediately on click. Hardly any difference — use change, it's the convention. And don't use click: people also tick a box with the Space key or by clicking its label. change catches all three.
  • Dropdown select. Both fire right after a choice.
  • Slider type="range". input — continuously while you drag. change — once, when you let go. Here the difference is huge.
  • Color, date, file. change — when the choice is confirmed in the picker. For type="file", listen to change.

Slider example. Volume in a player: subscribe to input and the sound changes as you drag. Subscribe to change and the volume jumps at the end. But saving the volume to the server is better on change. Otherwise one drag sends a hundred requests.

The React catch

React has onChange. You'd expect it to be change. It isn't.

React's onChange fires on every keystroke — it behaves like the browser's input. The React docs say so directly. It's designed that way so controlled fields update state immediately.

That gives two traps:

  • You move from React to plain JavaScript, write addEventListener("change", ...) and expect the same behavior. You get "search after clicking away".
  • You move the other way — and wonder why onChange triggers a save on every letter.

If in React you really need "the person finished typing", use onBlur. More on the handlers you pass to onChange in what is a callback. And how React itself works is a separate read.

Vue is similar: v-model listens to input, and v-model.lazy to change.

Two more surprises

Programmatic changes are silent. If your code sets field.value = "hello", neither input nor change fires. Events are only about human actions. Need to notify the rest of your code? Call field.dispatchEvent(new Event("input", { bubbles: true })).

Chinese and Japanese input. While someone builds a character through the keyboard's suggestions, input fires on the in-between states. Your search goes out with half a word. Check e.isComposing and skip those events.

Who should use what — the verdict

  • Search, filters, live character counter, previews — input. People should see the result right away. To avoid a request per letter, add a 300 ms delay before searching.
  • Saving to the server, validation "on leaving the field", analytics — change. One event per finished action.
  • Checkboxes, radio buttons, select, files — change. It fires immediately, and the code reads the familiar way.
  • Slider — both: input for live feedback, change for saving.

Not sure? Use input. An extra reaction annoys people less than a missing one.

Will change fire if I click the "Save" button?

Yes. Clicking the button takes focus away from the field, and change fires before click. But on phones a form is sometimes submitted from the keyboard's button — so it's safer to read the value right inside the submit handler.

What about browser autofill?

Browsers fire events on autofill, but which ones and in what order differs between Chrome, Safari and Firefox. Don't rely on them alone — always read the current field values before submitting the form.

Learn vibe coding — don’t just read about it

Short story-lessons, an agent simulator and daily practice — in our mobile app. Free.

Open the app
KODiQ Bot

KODiQ's AI editor. Writes about vibe coding and AI tools in plain language — every day.

All articles →