Namespaces make cleanup easy
Suffix any event with a namespace — 'click.menu', 'keydown.shortcuts' — and later remove exactly that group with .off('.menu'), leaving everyone else's handlers alone. This is the cleanest way to tear down a modal, a widget or a feature flag.
Shortcuts and handler signature
.click(fn), .change(fn), .submit(fn) and friends bind; calling them with no argument triggers the event. Handlers receive (event, detail), and this is the element — or, for delegated handlers, the matched descendant.
Press J / K to move the dot, ? for help — anywhere on this page.
Event log…
View the source for this demo
<p style="margin:0 0 12px">Press <kbd>J</kbd> / <kbd>K</kbd> to move the dot, <kbd>?</kbd> for help — anywhere on this page.</p>
<div class="row">
<button type="button" id="ev-toggle" aria-pressed="true">Shortcuts on</button>
<button type="button" id="ev-once">Claim one-time bonus</button>
<button type="button" id="ev-fake">Simulate “J”</button>
</div>
<div class="ev-meter" aria-hidden="true"><span id="ev-pos"></span></div>
<pre class="out" id="ev-log" aria-live="polite">Event log…</pre>let pos = 0;
const log = msg => $('#ev-log').text((msg + '\n' + $('#ev-log').text()).split('\n').slice(0, 6).join('\n'));
const move = d => {
pos = Math.max(0, Math.min(10, pos + d));
$('#ev-pos').css('left', 'calc(' + pos * 9 + '% + 5px)');
};
function bindShortcuts() {
$(document).on('keydown.shortcuts', e => {
if (e.target.closest && e.target.closest('input, textarea, select')) return;
if (e.key === 'j') { move(1); log('keydown.shortcuts → J (position ' + pos + ')'); }
if (e.key === 'k') { move(-1); log('keydown.shortcuts → K (position ' + pos + ')'); }
if (e.key === '?') log('Help: J moves right, K moves left');
});
}
bindShortcuts();
$('#ev-toggle').on('click', function () {
const on = $(this).attr('aria-pressed') !== 'true';
if (on) bindShortcuts();
else $(document).off('.shortcuts'); // removes only this namespace
$(this).attr('aria-pressed', String(on)).text(on ? 'Shortcuts on' : 'Shortcuts off');
log(on ? "on('keydown.shortcuts') bound" : "off('.shortcuts') — namespace removed, other handlers untouched");
});
$('#ev-once').one('click', function () {
log('.one() fired. Click again — nothing happens.');
$(this).text('Bonus claimed ✓');
});
$('#ev-fake').on('click', () => document.dispatchEvent(new KeyboardEvent('keydown', { key: 'j' })));More examples
The full toolbox
$('.btn').on('click mouseenter', handler); // several events
$('#dialog').on('keydown.modal', onKey); // namespaced
$('#dialog').off('.modal'); // remove the group
$('#intro').one('click', dismiss); // runs once
$('#save').click(save); $('#save').click(); // bind / trigger
$('.card').hover(lift, drop); // mouseenter + mouseleaveAPI
Attach handlers. Multiple space-separated events and .namespace suffixes are supported. With a delegate selector, the handler fires for matching descendants — including ones added later — and this is the matched element.
Like .on() but the handler runs at most once.
Remove handlers — all of them, by event type, by namespace, or by specific handler reference.
Reference: .off() →Dispatch an event (bubbling, cancelable). The optional payload arrives as the handler’s second argument.
Reference: .trigger() →With a handler: binds it. Without: triggers the event. Available for click, dblclick, change, input, submit, keydown, keyup, keypress, mousedown, mouseup, mousemove, mouseenter, mouseleave, scroll, resize, touchstart, touchend, contextmenu.
Bind a handler, or move focus when called without one.
Reference: .focus() / .blur() →Migrating
Event (no jQuery event wrapper), so use e.key, e.target, e.preventDefault() as usual. Legacy .bind(), .live(), .delegate() are not included — use .on().Related features
Event delegation
Handle clicks on thousands of rows — including rows added later — with a single listener using .on(event, selector, handler).
Open →CoreCustom events
Decouple your UI with custom events: trigger("cart:add", payload) once and let any number of independent listeners react.
Open →PulseEvent directives
Handle events right in your markup with @click and kj-on:, including the .prevent, .stop, .enter and .escape modifiers.
Open →