jQuery - 使用.on和.off为具有无名函数的事件侦听器

时间:2016-08-29 06:47:01

标签: javascript jquery html

我正在尝试利用我的JS中的.off()来处理在ajax请求期间关闭所有点击,然后在完成后将其重新打开。我知道要使用的代码是ajaxStart().ajaxStop()

我遇到的是我的.on('click')使用无名功能。即:$(document).on('click', '-enter-delegated-elements-here-', function (e) { // Click stuff here, like the click to run the ajax request });

这会产生一个问题,因为在我使用.off$(document).off('click', '**');)关闭我的事件监听器之后,我必须重新打开它们。 很遗憾,普通$(document).on('click', '-enter-delegated-elements-here-');不起作用。

为证明我的观点,我创建了this fiddle

(一个片段也在这里:)

$('add').on('click', '#add'); //here's the zinger!!!



var i = 0;
$('#add span').text(i);
$(document).on('click', '#add', function(e) {
  $('#catcher').append(i);
  i += 1;
  $('#add span').text(i);
});
$(document).on('click', '#stop', function(e) {
  if (!$(document).off('click', '#add')) {
    $(document).off('click', '#add');
    return;
  }
  $(this).text('Add five and re-enable catching');
  i += 5;
  $('#add span').text(i);
  $('add').on('click', '#add'); //here's the zinger!!!
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="add">
  Add to catcher: <span></span>
</button>
<button id="stop">
  Stop catching
</button>
<h2>Catcher:</h2>
<div id="catcher"></div>
&#13;
&#13;
&#13;

(虽然没有ajax请求,原则仍然相同)

我知道我可以创建一个函数来处理这个问题,即:

function forClicks(e) {
  // Click stuff here, like the click to run the ajax request
}
$(document).on('click', '-enter-delegated-elements-here-', forClicks(e));

然而,制作一堆函数变得不太实际(例如,如果你最终有多个点击处理程序 - to handle debouncers和诸如此类的东西等),并且当你可以使用无名函数时也会混乱全局空间代替。

  

有没有人知道我如何使用.on()(在使用.off()关闭之后)转回使用无名函数的事件处理程序?有没有办法做到这一点,还是需要其他类型的JS代码(我知道.toggle()不再起作用,但可能会有类似的东西?)。

1 个答案:

答案 0 :(得分:2)

至少有三种解决方案:

  1. 在ajax操作期间禁用按钮。这也有助于告诉用户他们在那段时间内不可用。

  2. 使用标志告诉处理者不要做任何事情,例如:

        <script type="text/javascript">
    
    $(document).ready(function () {
    
    $('#btnmenu').click(function () { $('#menu').show();
    
    }); });
    
    </script>
    
    <body style="margin:0px;padding:0px;">
        <form id="form1" runat="server">
    
            <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
    
             <div id="map_canvas">
    
        </div>
           <div>
                <asp:Button ID="btnmenu" runat="server" Text="Menu" />
            </div>
    
             <div class="tabsleft" id="menu" style="display:none">
    
        <ul >
        <li>
        <a><img class="imga" alt="dashboard" src="images/eve.bmp" border="0" />DASHBOARD</a>
        </li>
    
        </ul>
        </div>
    
    
        </form>
    </body>
    

    然后在启动ajax调用时递增它,并在调用结束时递减它(包括它是否失败)。

    然后在处理程序中:

    var disableClicks = 0;
    
  3. 如您所述,使用命名函数。

      

    我知道我可以创建一个函数来处理这个问题,即:

         

    然而,制作一堆函数变得不太实际(例如,如果你最终有多个点击处理程序 - 处理debouncers等等),并且当你可以使用无名函数时也会混乱全局空间。

    没有必要让它们全局化。您只需将它们放在您使用它们的范围内即可。你甚至可以将它们包装成一个漂亮整洁的控制器对象。

  4. #1的示例(禁用按钮):

    if (disableClicks) {
        return;
    }
    
    var i = 0;
    $('#add span').text(i);
    $(document).on('click', '#add', function(e) {
      $('#catcher').append(i);
      i += 1;
      $('#add span').text(i);
    });
    $(document).on('click', '#stop', function(e) {
      $("#add").prop("disabled", true);
      setTimeout(function() {
        $(this).text('Add five and re-enable catching');
        i += 5;
        $('#add span').text(i);
        $("#add").prop("disabled", false);
      }, 1000);
    });

    #2(标志/计数器)的例子:

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <button id="add">
      Add to catcher: <span></span>
    </button>
    <button id="stop">
      Stop catching
    </button>
    <h2>Catcher:</h2>
    <div id="catcher"></div>
    var disableClicks = 0;
    var i = 0;
    $('#add span').text(i);
    $(document).on('click', '#add', function(e) {
      if (disableClicks) {
        return;
      }
      $('#catcher').append(i);
      i += 1;
      $('#add span').text(i);
    });
    $(document).on('click', '#stop', function(e) {
      ++disableClicks;
      setTimeout(function() {
        $(this).text('Add five and re-enable catching');
        i += 5;
        $('#add span').text(i);
        --disableClicks;
      }, 1000);
    });

    #3(控制器对象)的示例:

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <button id="add">
      Add to catcher: <span></span>
    </button>
    <button id="stop">
      Stop catching
    </button>
    <h2>Catcher:</h2>
    <div id="catcher"></div>
    var addController = {
      handler: function(e) {
        $('#catcher').append(i);
        i += 1;
        $('#add span').text(i);
      },
      enable: function() {
        $(document).on('click', '#add', addController.handler);
      },
      disable: function() {
        $(document).off('click', '#add', addController.handler);
      }
    };
    addController.enable();
    
    var i = 0;
    $('#add span').text(i);
    $(document).on('click', '#stop', function(e) {
      addController.disable();
      setTimeout(function() {
        $(this).text('Add five and re-enable catching');
        i += 5;
        $('#add span').text(i);
        addController.enable();
      }, 1000);
    });