简体   繁体   中英

Jquery (2.2.0) click listener stops working after few clicks when using .on() but .click() works fine

I'm using bootstrap 3.3.6 with Jquery 2.2.0, and I'm trying to use .on() to set a click listener to my bootstrap dropdown menu items. The link clicks register a few clicks (2-3 usually), but then they stop working. If I use .click() , then the clicking continues to work without issue.

Exact steps taken:

  1. Use "My item 1" menu to "Move down"; this moves it beneath "My item 2"
  2. Use "My item 2" menu to "Move down"; this moves it beneath "My item 1"
  3. Use "My item 1" menu to "Move down"; this fails to move

JS Fiddle demonstrating issue here: https://jsfiddle.net/e8qgqv9r/3/

<script>
$('#my-items').on('click', '.my-item-menu li a', function() {  // FAILS
//$(document).on('click', '.my-item-menu li a', function() {  // FAILS
//$('.my-item-menu li a').click(function() {  // WORKS
  var link = $(this);
  var item = link.parent().parent().parent().parent().parent().parent();

  if(link.hasClass('move_up')) {
    if(item.index() > 0) {
      item.parent().children().eq(item.index() - 1).insertAfter(item);
    }
  }
  else if(link.hasClass('move_down')) {
    if(item.index() < item.parent().children().length - 1) {
      item.parent().children().eq(item.index() + 1).insertBefore(item);
    }
  }
  else if(link.hasClass('tlog_remove')) {
    item.remove();
  }
  link.closest('.my-item-menu').dropdown('toggle');
  return false;
});
</script>
<div id="my-items">
  <div class="well well-sm">
    <div class="row">
      <div class="col-md-8 col-sm-8 col-xs-8">
        <h4>My item 1</h4>
      </div>
      <div class="col-md-4 col-sm-4 col-xs-4">
        <div class="dropdown pull-right">
          <button id="menu-opt-btn-1" type="button" class="btn btn-default btn-sm" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            options
            <span class="caret"></span>
          </button>
          <ul class="my-item-menu dropdown-menu" aria-labelledby="menu-opt-btn-1">
            <li><a href="" class="move_up">Move up</a></li>
            <li><a href="" class="move_down">Move down</a></li>
            <li><a href="" class="remove_item">Remove item</a></li>
          </ul>
        </div>
      </div>
    </div>
  </div>

  <div class="well well-sm">
    <div class="row">
      <div class="col-md-8 col-sm-8 col-xs-8">
        <h4>My item 2</h4>
      </div>
      <div class="col-md-4 col-sm-4 col-xs-4">
        <div class="dropdown pull-right">
          <button id="menu-opt-btn-2" type="button" class="btn btn-default btn-sm" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            options
            <span class="caret"></span>
          </button>
          <ul class="my-item-menu dropdown-menu" aria-labelledby="menu-opt-btn-2">
            <li><a href="" class="move_up">Move up</a></li>
            <li><a href="" class="move_down">Move down</a></li>
            <li><a href="" class="remove_item">Remove item</a></li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</div>

Am I using .on() incorrectly, or is this a potential bug with jquery/bootstrap? (or my browser -- currently running Chrome 48.0.2564.103 (64-bit) on OS X?)

Not sure why, might have to do on how bootstraps dropdown plugin works, but you seem to be calling dropdown('toggle') on the wrong element. So it might be that doing a toggle on an element that isn't setup for dropdowns (eg isn't the data-toggle element) ends up having the bubbling of their events canceled in effect making it never reach your #my-items or document elements. But this is just a guess you would have to dive into their code to see for sure.

Switch

link.closest('.my-item-menu').dropdown('toggle');

to something like

link.closest('.dropdown').find("button").dropdown('toggle');

and it now works as expected

Demo

 $('#my-items').on('click', '.my-item-menu li a', function() { //$(document).on('click', '.my-item-menu li a', function() { //$('.my-item-menu li a').click(function() { var link = $(this); var item = link.parent().parent().parent().parent().parent().parent(); if(link.hasClass('move_up')) { if(item.index() > 0) { item.parent().children().eq(item.index() - 1).insertAfter(item); } } else if(link.hasClass('move_down')) { if(item.index() < item.parent().children().length - 1) { item.parent().children().eq(item.index() + 1).insertBefore(item); } } else if(link.hasClass('tlog_remove')) { item.remove(); } link.closest('.dropdown').find("button").dropdown('toggle'); return false; }); 
 <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.min.js"></script> <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> <script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> <div id="my-items"> <div class="well well-sm"> <div class="row"> <div class="col-md-8 col-sm-8 col-xs-8"> <h4>My item 1</h4> </div> <div class="col-md-4 col-sm-4 col-xs-4"> <div class="dropdown pull-right"> <button id="menu-opt-btn-1" type="button" class="btn btn-default btn-sm" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> options <span class="caret"></span> </button> <ul class="my-item-menu dropdown-menu" aria-labelledby="menu-opt-btn-1"> <li><a href="" class="move_up">Move up</a></li> <li><a href="" class="move_down">Move down</a></li> <li><a href="" class="remove_item">Remove item</a></li> </ul> </div> </div> </div> </div> <div class="well well-sm"> <div class="row"> <div class="col-md-8 col-sm-8 col-xs-8"> <h4>My item 2</h4> </div> <div class="col-md-4 col-sm-4 col-xs-4"> <div class="dropdown pull-right"> <button id="menu-opt-btn-2" type="button" class="btn btn-default btn-sm" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> options <span class="caret"></span> </button> <ul class="my-item-menu dropdown-menu" aria-labelledby="menu-opt-btn-2"> <li><a href="" class="move_up">Move up</a></li> <li><a href="" class="move_down">Move down</a></li> <li><a href="" class="remove_item">Remove item</a></li> </ul> </div> </div> </div> </div> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM