Avoid dropdown menu close on click inside

2019-01-01 06:28发布

I have a Twitter Bootstrap dropdown menu. As all Twitter Bootstrap users know, the dropdown menu closes on click (even clicking inside it).

To avoid this, I can easily attach a click event handler on the dropdown menu and simply add the famous event.stopPropagation().

<ul class="nav navbar-nav">
  <li class="dropdown mega-dropdown">
    <a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown">
      <i class="fa fa-list-alt"></i> Menu item 1
      <span class="fa fa-chevron-down pull-right"></span>
    </a>
    <ul class="dropdown-menu mega-dropdown-menu">
      <li>
        <div id="carousel" class="carousel slide" data-ride="carousel">
          <ol class="carousel-indicators">
            <li data-slide-to="0" data-target="#carousel"></li>
            <li class="active" data-slide-to="1" data-target="#carousel"></li>
          </ol>
          <div class="carousel-inner">
            <div class="item">
              <img alt="" class="img-rounded" src="img1.jpg">
            </div>
            <div class="item active">
              <img alt="" class="img-rounded" src="img2.jpg">
            </div>
          </div>
          <a data-slide="prev" role="button" href="#carousel" 
             class="left carousel-control">
            <span class="glyphicon glyphicon-chevron-left"></span>
          </a>
          <a data-slide="next" role="button" href="#carousel" 
             class="right carousel-control">
            <span class="glyphicon glyphicon-chevron-right"></span>
          </a>
        </div>
      </li>
    </ul>
  </li>
</ul>

This looks easy and a very common behavior, however, and since carousel-controls (as well as carousel indicators) event handlers are delegated to the document object, the click event on these elements (prev/next controls, ...) will be “ignored”.

$('ul.dropdown-menu.mega-dropdown-menu').on('click', function(event){
    // The event won't be propagated up to the document NODE and 
    // therefore delegated events won't be fired
    event.stopPropagation();
});

Relying on Twitter Bootstrap dropdown hide/hidden events is not a solution for the following reasons:

  • The provided event for both event handlers doesn’t give you reference to the clicked element
  • The dropdown menu content is dynamically generated so adding a flag class is not possible

This fiddle is the normal behavior and this fiddle is with event.stopPropagation() added.

Update

Thanks to Roman for his answer. I also found an answer that you can find below.

25条回答
有味是清欢
2楼-- · 2019-01-01 07:20

Instead of writing some javascript or jquery code(reinventing the wheel). The above scenario can be managed by bootstrap auto-close option. You can provide either of the values to auto-close:

  1. always - (Default) automatically closes the dropdown when any of its elements is clicked.

  2. outsideClick - closes the dropdown automatically only when the user clicks any element outside the dropdown.

  3. disabled - disables the auto close

Take a look at the following plunkr :

http://plnkr.co/edit/gnU8M2fqlE0GscUQtCWa?p=preview

Set

uib-dropdown auto-close="disabled" 

Hope this helps :)

查看更多
荒废的爱情
3楼-- · 2019-01-01 07:20

For closing the dropdown only if a click event was triggered outside the bootstrap dropdown, this is what worked for me:

JS file:

    $('.createNewElement').on('click.bs.dropdown.data-api', '.tags-btn-group.keep-open-dropdown', function (e) {
        var target = $(e.target);
        if (target.hasClass("dropdown-menu") || target.parents(".dropdown-menu").length) {
            e.stopPropagation();
        }
    });

HTML file:

<!-- button: -->
<div class="createNewElement">
                <div class="btn-group tags-btn-group keep-open-dropdown">

                    <div class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">OPEN DROPDOWN</div>

                    <ul class="dropdown-menu">
                        WHAT EVER YOU WANT HERE...
                    </ul>

                </div>
</div>
查看更多
刘海飞了
4楼-- · 2019-01-01 07:21

This might help:

$("dropdownmenuname").click(function(e){
   e.stopPropagation();
})
查看更多
回忆,回不去的记忆
5楼-- · 2019-01-01 07:21

[Bootstrap 4 Alpha 6][Rails] For rails developer, e.stopPropagation() will lead to undesirable behavior for link_to with data-method not equal to get since it will by default return all your request as get.

To remedy this problem, I suggest this solution, which is universal

$('.dropdown .dropdown-menu').on('click.bs.dropdown', function() {
  return $('.dropdown').one('hide.bs.dropdown', function() {
    return false;
  });
});

$('.dropdown .dropdown-menu').on('click.bs.dropdown', function() {
  return $('.dropdown').one('hide.bs.dropdown', function() {
    return false;
  });
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>

<ul class="nav navbar-nav">
  <li class="dropdown mega-dropdown">
    <a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown">
      <i class="fa fa-list-alt"></i> Menu item 1
      <span class="fa fa-chevron-down pull-right"></span>
    </a>
    <ul class="dropdown-menu mega-dropdown-menu">
      <li>
        <div id="carousel" class="carousel slide" data-ride="carousel">
          <ol class="carousel-indicators">
            <li data-slide-to="0" data-target="#carousel"></li>
            <li class="active" data-slide-to="1" data-target="#carousel"></li>
          </ol>
          <div class="carousel-inner">
            <div class="item">
              <img alt="" class="img-rounded" src="img1.jpg">
            </div>
            <div class="item active">
              <img alt="" class="img-rounded" src="img2.jpg">
            </div>
          </div>
          <a data-slide="prev" role="button" href="#carousel" class="left carousel-control">
            <span class="glyphicon glyphicon-chevron-left"></span>
          </a>
          <a data-slide="next" role="button" href="#carousel" class="right carousel-control">
            <span class="glyphicon glyphicon-chevron-right"></span>
          </a>
        </div>
      </li>
    </ul>
  </li>
</ul>

查看更多
呛了眼睛熬了心
6楼-- · 2019-01-01 07:22

You can stop click on the dropdown from propagating and then manually reimplement the carousel controls using carousel javascript methods.

$('ul.dropdown-menu.mega-dropdown-menu').on('click', function(event) {
    event.stopPropagation();
});

$('a.left').click(function () {
    $('#carousel').carousel('prev');
});

$('a.right').click(function () {
    $('#carousel').carousel('next');
});

$('ol.carousel-indicators li').click(function (event) {
    var index = $(this).data("slide-to");
    $('#carousel').carousel(index);
});

Here is the jsfiddle.

查看更多
后来的你喜欢了谁
7楼-- · 2019-01-01 07:23

Bootstrap provides the following function:

                 | This event is fired immediately when the hide instance method 
hide.bs.dropdown | has been called. The toggling anchor element is available as the 
                 | relatedTarget property of the event.

Therefore, implementing this function should be able to disable the dropdown from closing.

$('#myDropdown').on('hide.bs.dropdown', function (e) {
    var target = $(e.target);
    if(target.hasClass("keepopen") || target.parents(".keepopen").length){
        return false; // returning false should stop the dropdown from hiding.
    }else{
        return true;
    }
});
查看更多
登录 后发表回答