避免下拉菜单在内部点击时关闭

IT技术 javascript jquery html twitter-bootstrap-3 drop-down-menu
2021-02-09 04:46:50

我有一个 Twitter Bootstrap 下拉菜单。所有 Twitter Bootstrap 用户都知道,下拉菜单会在点击时关闭(甚至在其中点击)。

为了避免这种情况,我可以轻松地在下拉菜单上附加一个单击事件处理程序,然后简单地添加著名的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>

然而,这看起来很简单并且是一个非常常见的行为,并且由于carousel-controls(以及carousel indicators)事件处理程序被委托给document对象,click这些元素(上一个/下一个控件,...)事件将被“忽略”。

$('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();
});

由于以下原因,依靠 Twitter Bootstrap 下拉菜单hide/hidden事件不是解决方案:

  • 为两个事件处理程序提供的事件对象没有引用被点击的元素
  • 我无法控制下拉菜单内容,因此flag无法添加类或属性

这个小提琴是正常行为,这个小提琴event.stopPropagation()添加的。

更新

感谢罗曼的回答我还找到了您可以在下面找到的答案

6个回答

这也应该有帮助

$(document).on('click', 'someyourContainer .dropdown-menu', function (e) {
  e.stopPropagation();
});
我认为这肯定是解决这个问题的最简单的方法。竖起大拇指 - 刚刚测试了这个并且它有效!
2021-03-13 04:46:50
简单地在点击时保持菜单打开的最佳解决方案。
2021-03-15 04:46:50
这是最常见的解决方案,但我有不同的要求。请仔细阅读我的问题:)
2021-04-01 04:46:50
这是迄今为止最好的解决方案。
2021-04-07 04:46:50
确实是最好的解决方案。我个人使用'.dropdown-menu :not(.dropdown-item)'这样,点击 adropdown-item确实关闭弹出窗口,但点击 adropdown-header不会。
2021-04-07 04:46:50

删除数据属性data-toggle="dropdown"并实现下拉菜单的打开/关闭可以是一个解决方案。

首先通过点击链接来打开/关闭下拉菜单,如下所示:

$('li.dropdown.mega-dropdown a').on('click', function (event) {
    $(this).parent().toggleClass('open');
});

然后听下拉菜单外的点击以关闭它,如下所示:

$('body').on('click', function (e) {
    if (!$('li.dropdown.mega-dropdown').is(e.target) 
        && $('li.dropdown.mega-dropdown').has(e.target).length === 0 
        && $('.open').has(e.target).length === 0
    ) {
        $('li.dropdown.mega-dropdown').removeClass('open');
    }
});

这是演示:http : //jsfiddle.net/RomaLefrancois/hh81rhcm/2/

这个首选答案是一个黑客。哇!!!这是一个更简单的 BOOTSTRAP 4 ALPHA 答案,以防止大型下拉菜单中的内部点击。// PREVENT INSIDE CLICK DROPDOWN $('.dropdown-menu').on("click.bs.dropdown", function (e) { e.stopPropagation(); e.preventDefault(); });
2021-03-30 04:46:50
@Cichy...只需像这样修改第一个处理程序...$('li.dropdown.mega-dropdown a').on('click', function (event) { $('li.dropdown.mega-dropdown .open').removeClass('open'); $(this).parent().toggleClass('open'); });
2021-04-02 04:46:50
此解决方案运行良好。如果没有其他答案,应将赏金授予您。
2021-04-03 04:46:50
您的解决方案有效、通用且“流行”。赏金应该奖励给你的答案。我也找到了答案,请看下面;)
2021-04-04 04:46:50
e.stopPropagation() 是最好的解决方案。
2021-04-10 04:46:50

绝对最好的答案是在类下拉菜单之后放置一个表单标签

所以你的代码是

<ul class="dropdown-menu">
  <form>
    <li>
      <div class="menu-item">bla bla bla</div>
    </li>
  </form>
</ul>
在功能上对我来说非常好,但打破了造型
2021-03-13 04:46:50
感谢这个快速解决方案
2021-03-15 04:46:50
这在语义上不是正确的解决方案 - UL 的唯一有效子代是 LI - 如果有任何形式标签应该在 li 标签内 - 但这可能无法实现所需的操作 - 无论哪种方式 ul > form > li 都不是正确的标记
2021-03-25 04:46:50
这不是最佳答案 :)<li>元素不应位于<form> 元素内。
2021-04-04 04:46:50
这对我来说是最快的解决方案
2021-04-10 04:46:50

Bootstrap 提供了以下功能:

                 | 隐藏实例方法时立即触发此事件
hide.bs.dropdown | 已被调用。切换锚元素可用作
                 | 事件的相关目标属性。

因此,实现此功能应该能够禁用下拉菜单关闭。

$('#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;
    }
});
@webfish 你浏览互联网需要多少时间?(罗夫)
2021-03-17 04:46:50
也许这曾经有效..但是对于引导程序 4,e.target 始终是下拉菜单本身。不是点击的目标。即使你在下拉菜单之外点击,e.target 仍然是下拉菜单。所以你不能执行这种检查。有没有人看到解决这个问题的方法?
2021-03-17 04:46:50
@Vartan,事件target属性也是li.dropdownrelatedTargeta.dropdown-toggle所以你不能在hide事件处理程序中引用被点击的元素
2021-03-20 04:46:50
我已经浏览了互联网,这是迄今为止最智能的解决方案,出于这个原因...... msot 其他方法要求使用停止默认事件或停止传播的方法。这些方法非常糟糕,因为它们会破坏下拉列表中的任何其他触发事件(即我的 jquery 移动表单元素),使用这种方法可以让您专门识别菜单本身何时关闭,并允许您单独对该事件采取行动。这个答案需要这么多星....
2021-04-06 04:46:50
hasClass 需要一个类名,而不是一个 CSS 选择器。target.hasClass(".keepopen")应该是target.hasClass("keepopen")否则代码将无法工作。
2021-04-10 04:46:50

这可能有帮助:

$("dropdownmenuname").click(function(e){
   e.stopPropagation();
})
如果您希望用户与出现在下拉列表中的 UI 元素(例如单选按钮)进行交互并且不希望菜单在切换选项时关闭,这绝对是最简单/最好的答案。
2021-03-29 04:46:50