The handler's first argument
When jQuery runs a handler, it passes an event object describing what happened. Name it event or e:
<div id="box" style="padding: 20px; background: #e0f2fe">Click me</div>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
$("#box").on("click", function (event) {
console.log("type:", event.type);
console.log("target id:", event.target.id);
console.log("same as this?", event.currentTarget === this);
console.log("has timeStamp?", typeof event.timeStamp === "number");
});
</script>type: click
target id: box
same as this? true
has timeStamp? truejQuery's event object wraps the browser's native event and smooths over old browser differences. The original is available as event.originalEvent if you need a property jQuery does not copy.
target and currentTarget
Events start on the innermost element and then bubble up through its ancestors. So a click on text inside a button inside a list fires on all of them. Two properties tell you where you are:
<ul id="list">
<li>Plain item</li>
<li><strong>Bold</strong> item</li>
</ul>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
$("#list").on("click", function (event) {
console.log("target:", event.target.tagName);
console.log("currentTarget:", event.currentTarget.tagName);
console.log("closest li:", $(event.target).closest("li").text());
});
</script>target: STRONG
currentTarget: UL
closest li: Bold itemevent.targetis where the click actually happened: thestrong.event.currentTarget(andthis) is the element the handler is attached to: theul.
$(event.target).closest("li") finds the list item that was clicked, however deep the click landed. In arrow function handlers, use event.currentTarget where you would use this.
Preventing the default action
Many elements have a built-in default action: links navigate, forms submit and reload the page, checkboxes toggle. event.preventDefault() cancels it, so your code can do something else instead:
<a id="more" href="https://example.com/">Show more</a>
<p id="extra" hidden>Here is more text, loaded without leaving the page.</p>
<form id="search"><input name="q" value="lamps"><button>Search</button></form>
<p id="results"></p>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
$("#more").on("click", function (event) {
event.preventDefault();
$("#extra").prop("hidden", false);
console.log("link default prevented:", event.isDefaultPrevented());
});
$("#search").on("submit", function (event) {
event.preventDefault();
const q = $(this).find("[name=q]").val();
$("#results").text("Searching for " + q + "...");
console.log("form handled in JavaScript:", q);
});
</script>link default prevented: true
form handled in JavaScript: lampsPreventing a form's default submission is the first line of almost every Ajax form handler.
Stopping the bubble
Sometimes a click on an inner element should not also count as a click on its container. Call event.stopPropagation():
<div id="card" style="padding: 12px; border: 1px solid #ccc">
Product card (click to open)
<button id="delete">Delete</button>
</div>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
$("#card").on("click", function () {
console.log("card opened");
});
$("#delete").on("click", function (event) {
event.stopPropagation();
console.log("deleted, card not opened");
});
</script>deleted, card not openedWithout stopPropagation(), clicking Delete would also open the card. Use it sparingly: other code (analytics, a "click outside to close" menu) may rely on events reaching the document.
return false
In a jQuery handler, return false does both preventDefault() and stopPropagation(). It is common in older code. Being explicit is clearer, because it is easy to stop propagation by accident when you only wanted to stop a link.
Keys and mouse position
Keyboard events carry event.key, the value of the key, such as "a", "Enter", "Escape" or "ArrowDown". Mouse events carry coordinates:
| Property | Meaning |
|---|---|
event.pageX, event.pageY |
position relative to the whole document |
event.clientX, event.clientY |
position relative to the visible window |
event.offsetX, event.offsetY |
position inside the target element (via originalEvent) |
event.shiftKey, event.ctrlKey, event.altKey, event.metaKey |
whether a modifier key was held |
<input id="field" placeholder="Press Enter or Escape">
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
$("#field").on("keydown", function (event) {
if (event.key === "Enter") console.log("submit the search");
else if (event.key === "Escape") console.log("clear the field");
});
</script>clear the field
submit the searchOlder code uses the numbers event.which or event.keyCode (13 for Enter, 27 for Escape). They are deprecated in browsers and unreliable for anything but basic keys; prefer event.key.
Passing your own data
.on() accepts an optional data object before the handler; it arrives as event.data:
$("#plus").on("click", { step: 1 }, changeCount);
$("#minus").on("click", { step: -1 }, changeCount);
function changeCount(event) {
count += event.data.step;
}Common mistakes
- Forgetting
event.preventDefault()in a form or link handler, so the page reloads or navigates. - Using
event.targetwhen you meant the element with the handler; nested elements make them differ. - Stopping propagation everywhere, which breaks other features.
- Relying on
whichorkeyCodein new code.
Exercise
Build a link that, when clicked with the Shift key held, logs opening in a new view, and otherwise logs normal click. In both cases, prevent the browser from following the link.
Show one possible answer
<a id="link" href="https://example.com/">Open</a>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
$("#link").on("click", function (event) {
event.preventDefault();
console.log(event.shiftKey ? "opening in a new view" : "normal click");
});
</script>Key points
- Every handler receives an event object as its first argument, usually named event or e.
- event.target is the element the event started on; event.currentTarget is the element the handler is attached to.
- event.preventDefault() stops the browser's default action, such as following a link or submitting a form.
- Events bubble up through ancestors; event.stopPropagation() stops that, and return false does both.