2

I'm trying to unbind / off all events of every element inside one element. I tried this solution but it doesn't work. The only thing worked was $(document).add('*').off(); but this is not what I need.

I made a short example, but there are more elements and events.
Why it isn't working this code?

$(document).ready(function() {

    $(document).on("click", "#contentWithEvents button", function() {
        console.log("Clicked");
    });

    $(document).on("mouseenter", "#contentWithEvents li div", function() {
        console.log("Hovered");
    });

    $(document).on("click", "#unbind", function() {
        contentToBeReplaced = $("#contentWithEvents");
        contentToBeReplaced.find("*").each(function() {
            $(this).off();
        });
    });

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header></header>

<main id="contentWithEvents">

    <button>Click event</button>
    <button>Click event</button>
    <button>Click event</button>
    
    <ul>
      <li><div>Hover event</div></li>
      <li><div>Hover event</div></li>
    </ul>
    
</main>

<button id="unbind">Unbind all events</button>

<footer></footer>
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
SilverSurfer
  • 4,281
  • 6
  • 24
  • 50

3 Answers3

4

Instead of delegating document events with $(document) why not delegate the elements directly with the selectors containing parent id and element type. This would help to unbind the events of those elements using off() (specific events: .off('mouseenter') or all events: .off())

$(document).ready(function() {

  $("#contentWithEvents button").on("click", function() {
    console.log("Clicked");
  });

  $("#contentWithEvents li div").on("mouseenter", function() {
    console.log("Hovered");
  });

  $("#unbind").on("click", function() {
    contentToBeReplaced = $("#contentWithEvents");
    contentToBeReplaced.find("*").off();
  });

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header></header>

<main id="contentWithEvents">

  <button>Click event</button>
  <button>Click event</button>
  <button>Click event</button>

  <ul>
    <li>
      <div>Hover event</div>
    </li>
    <li>
      <div>Hover event</div>
    </li>
  </ul>

</main>

<button id="unbind">Unbind all events</button>

<footer></footer>
shrys
  • 5,860
  • 2
  • 21
  • 36
2

It seems the best way is to delegate on class selector and then remove the class when you want to no longer respond to the events

Also I have removed the delegation on the main and button since they have an ID. If they are dynamically generated, they do need to be delegated from nearest static container

$(document).ready(function() {

  $("#contentWithEvents").on("click", ".delegated", function() {
    console.log("Clicked");
  });

  $("#contentWithEvents").on("mouseenter", ".delegated", function() {
    console.log("Hovered");
  });

  $("#unbind").on("click", function() {
    $("#contentWithEvents .delegated").removeClass("delegated");
  });

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header></header>

<main id="contentWithEvents">

  <button class="delegated">Click event</button>
  <button class="delegated">Click event</button>
  <button class="delegated">Click event</button>

  <ul>
    <li>
      <div class="delegated">Hover event</div>
    </li>
    <li>
      <div class="delegated">Hover event</div>
    </li>
  </ul>

</main>

<button id="unbind">Unbind all events</button>

<footer></footer>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
1

it's quite simple actually you were just using the .off () command in the wrong way

$(document).ready(function() {

    $(document).on("click", "#contentWithEvents button", function() {
        console.log("Clicked");
    });

    $(document).on("mouseenter", "#contentWithEvents li div", function() {
        console.log("Hovered");
    });

    $(document).on("click", "#unbind", function() {
        $(document).off( "click", "#contentWithEvents button" );
        $(document).off( "mouseenter", "#contentWithEvents li div" );
    });

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header></header>

<main id="contentWithEvents">

    <button>Click event</button>
    <button>Click event</button>
    <button>Click event</button>
    
    <ul>
      <li><div>Hover event</div></li>
      <li><div>Hover event</div></li>
    </ul>
    
</main>

<button id="unbind">Unbind all events</button>

<footer></footer>
Lucas
  • 275
  • 8
  • 37