Himanshu SharmaSoftware engineer
Let’s talk

jQuery · Lesson 24 of 45

Keyboard and input events

Respond to typing with jQuery keydown, keyup and input events, read event.key, build live search and character counters, and add keyboard shortcuts safely.

12 minEventsUpdated 23 October 2026

By the end of this lessonChoose between keydown, keyup and input, react to specific keys, and update the page as the user types without slowing it down.

Three events for typing

When the user types in a field, several events fire for each key:

  1. keydown: the key went down. The character has not been inserted yet.
  2. input: the field's value changed.
  3. keyup: the key came back up.
html
<input id="name" placeholder="Type here">

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  $("#name")
    .on("keydown", e => console.log("keydown", e.key, "| value before:", JSON.stringify(e.target.value)))
    .on("input",   e => console.log("input   | value now:", JSON.stringify(e.target.value)))
    .on("keyup",   e => console.log("keyup  ", e.key));
</script>
result
keydown H | value before: ""
input   | value now: "H"
keyup   H
keydown i | value before: "H"
input   | value now: "Hi"
keyup   i

Notice that during keydown the value does not yet include the new letter.

Use input for live updates

If you want to react to what is in the field, listen for input. It fires for every change, however it happens: typing, pasting with the mouse, autofill, voice dictation, or dragging text in. Key events miss most of those.

A character counter is a typical example:

html
<textarea id="bio" maxlength="40" rows="2" cols="40"></textarea>
<p><span id="left">40</span> characters left</p>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  $("#bio").on("input", function () {
    const left = 40 - $(this).val().length;
    $("#left").text(left).css("color", left < 10 ? "crimson" : "");
  });
  $("#bio").on("input", function () {
    if ($(this).val().length === 12) console.log("left:", $("#left").text());
  });
</script>
result
left: 28

The older keypress event is deprecated in browsers; do not use it in new code.

Reacting to particular keys

Use keydown and check event.key when the key matters rather than the value: Enter to submit, Escape to close, arrows to move through a list.

html
<input id="q" placeholder="Use the arrow keys">
<ul id="suggestions"><li>Lamp</li><li>Desk</li><li>Chair</li></ul>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  let active = -1;
  const $items = $("#suggestions li");

  $("#q").on("keydown", function (event) {
    if (event.key === "ArrowDown") active = Math.min(active + 1, $items.length - 1);
    else if (event.key === "ArrowUp") active = Math.max(active - 1, 0);
    else if (event.key === "Enter") { console.log("chosen:", $items.eq(active).text()); return; }
    else return;

    event.preventDefault();   // stop the cursor jumping in the input
    $items.css("background", "").eq(active).css("background", "#fde68a");
    console.log("highlighted:", $items.eq(active).text());
  });
</script>
result
highlighted: Lamp
highlighted: Desk
highlighted: Lamp
chosen: Lamp

Down, down, up and Enter moved the highlight to Lamp, then Desk, back to Lamp, and chose it. Calling preventDefault() for the arrow keys stops their normal effect (moving the text cursor).

Blocking characters

Because keydown happens before the character is inserted, cancelling it stops the typing. For example, a field that accepts only digits:

html
<input id="pin" inputmode="numeric" placeholder="Digits only">

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  $("#pin").on("keydown", function (event) {
    const allowed = /^[0-9]$/.test(event.key) || event.key.length > 1;   // digits, or keys like Backspace and Tab
    if (!allowed) event.preventDefault();
  });
  $("#pin").on("input", function () {
    $(this).val($(this).val().replace(/\D/g, ""));   // also clean pasted text
    console.log("value:", $(this).val());
  });
</script>
result
value: 1
value: 12
value: 123
value: 1234

Keys with long names, like Backspace, Tab and the arrows, are always allowed, so the field stays usable. The letters a and b were blocked, so the value grew 1, 12, 123, 1234. The input handler is a second line of defence for pasted text, which never fires keydown. Always validate again on the server: users can bypass any browser check.

Debouncing: wait for a pause

Running a search request on every key wastes requests. Debouncing waits until the user stops typing for a moment:

html
<input id="search" placeholder="Search products">
<p id="status"></p>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  let timer;
  $("#search").on("input", function () {
    clearTimeout(timer);
    const term = $(this).val().trim();
    timer = setTimeout(function () {
      $("#status").text("Searching for " + term);
      console.log("search sent for:", term);
    }, 300);
  });
</script>
result
search sent for: lamp

Typing four letters scheduled the search four times, but each new letter cancelled the previous timer, so only one search ran, for the whole word.

Keyboard shortcuts

To add a shortcut for the whole page, listen on document, and ignore keys typed into fields:

javascript
$(document).on("keydown", function (event) {
  if ($(event.target).is("input, textarea, select, [contenteditable]")) return;
  if (event.key === "/") {
    event.preventDefault();
    $("#search").trigger("focus");
  }
});

Avoid shortcuts that clash with the browser or screen readers, and never make a shortcut the only way to do something.

Common mistakes

  • Using keyup for live updates, which misses pasting and autofill. Use input.
  • Using keypress, which is deprecated.
  • Checking event.keyCode numbers instead of event.key.
  • Sending a request on every key instead of debouncing.
  • Page-wide shortcuts that fire while the user types in a field.

Exercise

Make an input that shows, below it, the text typed so far in capital letters, updating live. When the user presses Escape, clear the input and the preview.

Show one possible answer
html
<input id="t">
<p id="upper"></p>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  $("#t")
    .on("input", function () { $("#upper").text($(this).val().toUpperCase()); })
    .on("keydown", function (event) {
      if (event.key === "Escape") { $(this).val(""); $("#upper").text(""); console.log("cleared"); }
    });
</script>
result
cleared

Key points

  • input fires whenever a field's value changes, including paste, autofill and voice typing; use it for live updates.
  • keydown fires when a key is pressed and can be cancelled; keyup fires when it is released.
  • event.key holds the key's value, such as "Enter", "Escape", "ArrowDown" or "a".
  • For work that is expensive, such as a search request, wait until the user pauses typing (debouncing).

Check yourself

1. Which event catches a value pasted with the mouse?
2. Which event can stop a key from typing a character with preventDefault()?
3. What is event.key when the user presses the Escape key?
4. What is the point of debouncing a live search?