Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JQuery. Removing all listeners on delegated events

I have container with some elements. They have some delegated event listeners.

Like this

$('body').on('click', '.container .button', function() { ... });

I want to remove all listeners from all elements in the container (whatever event type and selector).

Like this

 $( "body" ).off("*", ".container *");

But it doesn't work.

Can anyone help? Thanks for your help in advance.

like image 469
see613 Avatar asked Jan 11 '23 00:01

see613


1 Answers

Updated answer:

In the comments, you've said:

Ok. I have a jsfiddle to explain the issue. http://jsfiddle.net/KT42n/3 I want to remove all handlers from all elements IN THE CONTAINER

and

unfortunately in my case using of namespace is impossible

Ouch. That's going to make it very difficult, not least because some of the delegated handlers may relate to elements both inside and outside the container.

The only thing that comes to mind requires listing all of the event names you want to prevent (there aren't all that many):

$(".container").on("click mousedown mouseup etc.", false);

That will stop the event before it reaches body, and therefore before the delegated handler sees it: Live Example

<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<meta charset=utf-8 />
<title>Stop Delegated Handlers Within Container</title>
</head>
<body>
  <p>Outside the container</p>
  <div class="container">
    <p>Inside the container</p>
  </div>
  <script>
    (function() {
      // Other handlers
      $("body").on("click", "p", function() {
        display("paragraph clicked");
      });

      // Prevent clicks within container
      $(".container").on("click mousedown etc", false);

      function display(msg) {
        var p = document.createElement('p');
        p.innerHTML = String(msg);
        document.body.appendChild(p);
      }
    })();
  </script>
</body>
</html>

Original answer:

You can remove all handlers from body like this:

$("body").off();

That includes the delegated ones.

If you want to keep some of the handlers but not others, the simplest way I can think of is to namespace the events when you hook them up, e.g.:

$("body").on("click.foo", "selector", ...);

...and such. Then you can use the namespace to remove all of them:

$("body").off(".foo", "selector");

...or even just

$("body").off(".foo");

...to remove all of the namespaced ones entirely, not just the ones for that selector.

Example: Live Copy

<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<meta charset=utf-8 />
<title>Removing All Delegated Handlers</title>
</head>
<body>
  <div class="clickable">Click me</div>
  <div class="mousemoveable">Mouse over me</div>
  <input type="button" id="theButton" value="Remove handlers">
  <script>
    (function() {
      $("body").on("click.foo", ".clickable", function() {
        display("click");
      });
      $("body").on("mousemove.foo", ".mousemoveable", function() {
        display("mousemove");
      });
      $("#theButton").click(function() {
        $("body").off(".foo");
      });
      function display(msg) {
        var p = document.createElement('p');
        p.innerHTML = String(msg);
        document.body.appendChild(p);
      }
    })();
  </script>
</body>
</html>
like image 64
T.J. Crowder Avatar answered Jan 18 '23 01:01

T.J. Crowder