jQuery .off() Method

Beginner
7 min read
Updated: Oct 2026
5 examples
Live preview

What Is .off()?

.off(events [, selector] [, handler]) removes handlers attached with .on() (since 1.7). Filter by event type, namespace, delegation selector, and/or function reference.

Remember
$("#btn").on("click", fn);
$("#btn").off("click", fn);          // remove that handler

$("body").on("click", "#theone", flash);
$("body").off("click", "#theone", flash); // same selector required

$("form").off(".validator");         // all handlers in that namespace
$("p").off();                        // remove everything on p
$("p").off("click", "**");           // all delegated clicks only
NeedUse
Attach handlers.on()
Remove handlers.off()
Legacy direct unbind.unbind()
Legacy live unbind.die() (removed)
Legacy delegate unbind.undelegate()

How to Use .off()

Match the same filters you used when calling .on().

  1. Attach with .on() (direct or delegated).
  2. Decide what to remove: all, one event type, a namespace, a selector, and/or a function.
  3. Call .off() with those same filters on the same element(s).
  4. For delegated handlers, pass the exact original selector string.
  5. In shared code, prefer namespaces over bare .off("click").
FormRole
.off()Remove all handlers on the element(s)
.off(events [, selector] [, handler])Filter by type / namespace / selector / function
.off(eventsObject [, selector])Map of event → handler (or false)
.off(event)Remove using a jQuery.Event object

Pseudocode

Pseudocode
handlers were attached with .on(...)

call .off(optional EVENTS, optional SELECTOR, optional HANDLER):

    if no args:
        remove all handlers on these elements
    else:
        keep only handlers that match EVERY filter you passed

delegated note:
    SELECTOR must equal the original .on() selector
    "**" means “any delegated selector” for that event

Cheat Sheet

Keep these removal patterns handy.

TopicDetail
ReturnsjQuery (chainable)
Since1.7
Pairs with.on()
Namespace.off(".myPlugin") clears that namespace
"**"All delegated handlers of that event type
Selector ruleMust match the original delegated selector exactly
Proxy tipPrefer namespaces when unbinding proxied handlers

Live Preview

Bind a delegated click, fire it, then remove it with .off().

Run bind, click the target, then try an off action.

Status
Ready — Run “bind”, then click Target.

jQuery Examples

Short, copy-ready snippets. Pair every .on() with a matching .off() when cleaning up.

Example 1 — Delegated Bind / Off

Attach a delegated click, then remove it with the same selector.

jQuery
function flash() {
  $("#out").text("Clicked!");
}

$("#bind").on("click", function () {
  $("body").on("click", "#theone", flash);
  $("#theone").text("Can Click!");
});

$("#unbind").on("click", function () {
  $("body").off("click", "#theone", flash);
  $("#theone").text("Does nothing...");
});
Try It Yourself

How It Works

  1. On. Handler lives on body, filtered by #theone.
  2. Click. Matching clicks bubble up and run flash.
  3. Off. Same event, selector, and function remove that entry.
  4. After. Clicks on the target no longer call flash.

Example 2 — Remove All Handlers

No arguments — wipe every handler on the matched elements.

jQuery
$("p").on("click", fn1);
$("p").on("mouseover", fn2);

$("p").off(); // both gone
Try It Yourself

How It Works

  1. Attach. Multiple event types on the same elements.
  2. Broad off. Empty .off() clears all of them.
  3. Use. Handy for teardown; risky for shared elements.
  4. Safer. Prefer event names or namespaces in shared UI.

Example 3 — Remove One Handler Function

Pass the same function reference you used with .on().

jQuery
var foo = function () {
  $("#out").text("foo ran");
};

$("body").on("click", "p", foo);
$("body").off("click", "p", foo);
Try It Yourself

How It Works

  1. Named fn. Keep a stable function reference.
  2. On. Bind that exact function.
  3. Off. Pass the same function as the third argument.
  4. Other handlers. Unrelated click handlers can remain.

Example 4 — Remove by Namespace

Clear every handler in a plugin namespace at once.

jQuery
$("form").on("click.validator", "button", validate);
$("form").on("keypress.validator", "input", validate);

$("form").off(".validator"); // both removed
Try It Yourself

How It Works

  1. Tag. Append .validator when binding.
  2. Group. Several event types share that namespace.
  3. Off. .off(".validator") removes the whole group.
  4. Isolate. Other code’s handlers are left alone.

Example 5 — "**" Delegated Only

Remove all delegated clicks without touching direct ones.

jQuery
$("#list").on("click", "li", onItem); // delegated
$("#list").on("click", onList);       // direct

$("#list").off("click", "**"); // removes onItem only
Try It Yourself

How It Works

  1. Two kinds. Direct handlers sit on the element; delegated ones filter children.
  2. Star. "**" means any delegated selector for that event.
  3. Keep. Direct click on #list remains.
  4. Use. Clear child delegation without resetting the parent’s own handlers.

Edge Cases & Pitfalls

Common mistakes when removing handlers.

selector

Delegated selector must match exactly

.on("click", "li.item", fn) is not removed by .off("click", "li", fn).

broad

.off("click") is wide

It removes both direct and delegated click handlers on that element — use namespaces when sharing.

proxy

Proxied handlers share ids

Passing a proxied function to .off() can remove more than you intend — prefer namespaces.

anonymous

Anonymous functions are hard to target

Keep a named reference, or remove by event type / namespace instead of by function.

Browser Support

.off() has been part of jQuery since 1.7 and remains the standard way to remove handlers. It works wherever your loaded jQuery version runs.

✓ Stable · jQuery 1.7+

.off()

Works in every browser that runs your loaded jQuery version. Prefer a current jQuery 3.x build for modern projects.

100% With jQuery 1.7+
Google Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All modern versions
Full support
.off() Universal

Bottom line: Production-ready. Use namespaces for safe cleanup in plugins and shared pages.

Performance Notes

ApproachCostBest for
Namespaced .off()TinyPlugin / widget teardown
Leaving orphaned handlersMemory leak riskAlways off when removing dynamic UI
Repeated bind without offHigherHandlers stack — off before re-on

Removing a handler is cheap. The expensive mistake is never removing them when elements or widgets are destroyed.

Key Takeaways

  • Role: remove handlers attached with .on().
  • Match: use the same event, selector, and function you used with .on().
  • Namespaces: safest cleanup for plugins — .off(".myPlugin").
  • "**": strip all delegated handlers of an event type, keep direct ones.

One line: .off() is the modern undo for .on() — filter carefully, prefer namespaces.

Frequently Asked Questions

.off() removes event handlers attached with .on(). Since jQuery 1.7 it is the standard unbind API for both direct and delegated handlers, replacing .unbind(), .undelegate(), and .die().
It removes all handlers from the matched elements — direct and delegated. Prefer narrower filters (event type, namespace, selector, or handler) unless you are tearing a widget down.
Pass the same selector you used with .on(). Example: $(body).on("click", "#theone", fn) then $(body).off("click", "#theone", fn). A mismatched selector will not remove it.
$(el).off("click", "**") removes all delegated click handlers from el without removing direct click handlers bound on el itself.
Namespaces such as click.myPlugin let you remove only your handlers with .off(".myPlugin") without touching other code. Best practice for plugins and large apps.
.unbind() only covered direct binds; .die() only removed .live() handlers (both legacy). .off() works with everything attached via .on(), including delegation.

Next: .unbind()

See the legacy direct-unbind API that .off() replaced.

.unbind() tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful