You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用jQuery实现Bootstrap嵌套Popover子菜单的问题求助

解决Bootstrap 3嵌套Popover的实现问题

我来帮你搞定这个嵌套Popover的问题~你的代码主要卡在动态元素事件绑定和事件冒泡这两个点上,下面一步步给你修正:

问题根源分析

  1. 第一个Popover的内容是通过$('#menu1').html()复制生成的,这意味着Popover里的<li id="instance_1">是全新的元素,你之前直接绑定在[data-toggle="popover2"]上的事件并没有作用在这个新元素上。
  2. 点击子Popover触发元素时,事件会向上冒泡到父Popover容器,导致父Popover被意外关闭。

解决方案及修改代码

我们需要调整事件绑定方式、阻止冒泡,并优化Popover的触发逻辑,下面是修改后的完整代码:

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<button type="button" class="btn btn-lg btn-primary" data-toggle="popover1">
  Click to toggle popover
</button>

<!-- 原菜单作为模板隐藏,避免直接显示在页面 -->
<ul id="menu1" class="dropdown-menu hidden">
  <li data-toggle="popover2" style="cursor:pointer">Instance 1</li>
  <li>Instance 2</li>
</ul>
<ul id="menu2" class="dropdown-menu hidden">
  <li>Instance 3</li>
  <li>Instance 4</li>
</ul>

<script>
// 初始化父级Popover
$('[data-toggle="popover1"]').popover({
  html: true,
  placement: 'auto right',
  container: 'body',
  trigger: 'click',
  template: '<div id="x" class="popover" role="tooltip"><div class="arrow"></div><div class="popover-content"><div class="data-content"></div></div></div>',
  content: function () {
    return $('#menu1').html();
  }
});

// 用事件委托绑定子Popover,适配动态生成的元素
$('body').on('click', '[data-toggle="popover2"]', function(e) {
  // 阻止事件冒泡,避免父Popover被关闭
  e.stopPropagation();
  
  // 手动初始化并切换子Popover,避免重复绑定
  $(this).popover({
    html: true,
    placement: 'auto right',
    container: 'body',
    trigger: 'manual',
    template: '<div id="y" class="popover" role="tooltip"><div class="arrow"></div><div class="popover-content"><div class="data-content"></div></div></div>',
    content: function () {
      return $('#menu2').html();
    }
  }).popover('toggle');
});

// 点击页面空白处关闭所有Popover
$(document).on('click', function(e) {
  const isPopoverElement = $(e.target).closest('.popover').length;
  const isTriggerButton = $(e.target).is('[data-toggle="popover1"]');
  if (!isPopoverElement && !isTriggerButton) {
    $('[data-toggle="popover1"]').popover('hide');
    $('[data-toggle="popover2"]').popover('hide');
  }
});
</script>

关键改动说明

  1. 给原菜单加上hidden类,让它们只作为模板存在,不直接显示在页面上。
  2. 使用$('body').on('click', '[data-toggle="popover2"]', ...)的事件委托方式,确保动态生成的Instance 1元素能触发子Popover。
  3. 添加e.stopPropagation()阻止事件冒泡,避免父Popover被意外关闭。
  4. 将子Popover的trigger设为manual,手动调用popover('toggle'),防止重复绑定事件导致的异常。
  5. 新增页面空白点击事件,点击其他区域时自动关闭所有Popover,提升交互体验。

这样修改后,点击父Popover里的Instance 1就能正常弹出子Popover,而且父Popover不会被关闭啦~

内容的提问来源于stack exchange,提问作者Naveen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:29:27