Himanshu SharmaSoftware engineer
Let’s talk

jQuery · Lesson 27 of 45

Removing handlers: off, one and namespaces

Remove event handlers with jQuery .off(), run a handler only once with .one(), and use namespaces to remove only your own handlers without breaking others.

10 minEventsUpdated 23 October 2026

By the end of this lessonTurn behaviour on and off cleanly, avoid handlers being attached twice, and manage handlers in code shared with plugins.

Turning a handler off

.off() is the opposite of .on(). To remove a specific handler, pass the same event name and the same function you attached:

html
<button id="hit">Hit</button>
<button id="stop">Stop counting</button>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  let hits = 0;
  function count() {
    hits++;
    console.log("hits:", hits);
  }

  $("#hit").on("click", count);
  $("#stop").on("click", function () {
    $("#hit").off("click", count);
    console.log("counting stopped");
  });
</script>
result
hits: 1
hits: 2
counting stopped

The third click on Hit, after Stop, did nothing. To remove a handler you need a reference to it, which is one more reason to use named functions for handlers you may turn off. An anonymous function written inline cannot be passed to .off(), because writing the same code again creates a different function.

Removing all handlers of a type

.off("click") with no function removes every click handler on the element that was attached with jQuery. .off() with no arguments removes all handlers of all types. This is blunt: it also removes handlers that other code, such as a plugin or a theme, attached to the same element.

For delegated handlers, pass the same selector: $("#list").off("click", "li").

Running once with .one()

.one() attaches a handler that removes itself after it runs:

html
<button id="welcome">Show welcome tip</button>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  $("#welcome").one("click", function () {
    console.log("Tip: press / to search");
    $(this).text("Tip shown");
  });
  $("#welcome").on("click", () => console.log("button clicked"));
</script>
result
Tip: press / to search
button clicked
button clicked
button clicked

The tip ran on the first click only; the ordinary handler ran every time. If .one() is attached to several elements, it runs once per element.

A practical use is stopping double submissions: attach the submit handler with .one() (or disable the button on the first submit) so an impatient double-click does not send an order twice.

The stacking bug

A very common bug in jQuery code: a handler is attached inside something that runs repeatedly, so copies pile up.

html
<button id="open">Open dialog</button>
<button id="save">Save</button>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  let saves = 0;
  $("#open").on("click", function () {
    // Bug: a new copy of the handler is added every time the dialog opens
    $("#save").on("click", () => saves++);
  });
  $("#save").on("click", () => setTimeout(() => console.log("save ran", saves, "time(s) for one click")));
</script>
result
save ran 3 time(s) for one click

The dialog was opened three times, so one click on Save ran the handler three times. In a real app that could mean three identical orders. Fixes, from best to quickest:

  1. attach the handler once, outside the code that repeats;
  2. use delegation, attached once;
  3. remove before adding: $("#save").off("click.dialog").on("click.dialog", save), which uses a namespace, explained next.

Namespaces

A namespace is a label after a dot in the event name: click.menu, keydown.search. It does not change when the handler runs; it lets you refer to a group of handlers later:

html
<button id="btn">Button</button>
<button id="remove">Remove my handlers</button>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  // Another script's handler
  $("#btn").on("click", () => console.log("analytics: click recorded"));

  // Our handlers, labelled with the namespace .tip
  $("#btn").on("click.tip", () => console.log("tip: shown"));
  $("#btn").on("mouseenter.tip", () => console.log("tip: hover"));

  $("#remove").on("click", function () {
    $("#btn").off(".tip");
    console.log("removed .tip handlers");
  });
</script>
result
analytics: click recorded
tip: shown
removed .tip handlers
analytics: click recorded

.off(".tip") removed both of our handlers (click and mouseenter) and left the analytics handler alone. Plugin authors use namespaces so that their cleanup code never removes the site's own handlers. Use them whenever your code shares elements with other code.

You can also trigger only namespaced handlers: .trigger("click.tip") runs the .tip click handlers and not the others.

Common mistakes

  • Trying to remove an anonymous function with .off().
  • Calling .off("click") and removing other scripts' handlers.
  • Attaching handlers inside repeated code, so they stack.
  • Forgetting the selector when removing a delegated handler.

Exercise

Make a Subscribe button that, when clicked, logs subscribed and then cannot log again however often it is clicked. Do it in two ways: with .one(), and with .on() plus .off() using a namespace.

Show one possible answer
html
<button id="s1">Subscribe (one)</button>
<button id="s2">Subscribe (off)</button>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  $("#s1").one("click", () => console.log("subscribed"));

  $("#s2").on("click.subscribe", function () {
    console.log("subscribed");
    $(this).off(".subscribe");
  });
</script>
result
subscribed
subscribed

Key points

  • .off("click", handler) removes that handler; .off("click") removes every click handler on the element.
  • .one("click", handler) runs the handler at most once per element, then removes it.
  • Namespaces like "click.menu" label handlers, so .off(".menu") removes only yours.
  • Attaching a handler inside code that runs repeatedly stacks copies; remove first or attach once.

Check yourself

1. What does $("#b").off("click") remove?
2. What does .one("click", fn) do?
3. Why use a namespace such as click.tooltip?
4. A button's handler is attached inside a function that runs every time a dialog opens. After opening it three times, what happens on one click?