使用jQuery实现Bootstrap嵌套Popover子菜单的问题求助
解决Bootstrap 3嵌套Popover的实现问题
我来帮你搞定这个嵌套Popover的问题~你的代码主要卡在动态元素事件绑定和事件冒泡这两个点上,下面一步步给你修正:
问题根源分析
- 第一个Popover的内容是通过
$('#menu1').html()复制生成的,这意味着Popover里的<li id="instance_1">是全新的元素,你之前直接绑定在[data-toggle="popover2"]上的事件并没有作用在这个新元素上。 - 点击子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>
关键改动说明
- 给原菜单加上
hidden类,让它们只作为模板存在,不直接显示在页面上。 - 使用
$('body').on('click', '[data-toggle="popover2"]', ...)的事件委托方式,确保动态生成的Instance 1元素能触发子Popover。 - 添加
e.stopPropagation()阻止事件冒泡,避免父Popover被意外关闭。 - 将子Popover的
trigger设为manual,手动调用popover('toggle'),防止重复绑定事件导致的异常。 - 新增页面空白点击事件,点击其他区域时自动关闭所有Popover,提升交互体验。
这样修改后,点击父Popover里的Instance 1就能正常弹出子Popover,而且父Popover不会被关闭啦~
内容的提问来源于stack exchange,提问作者Naveen
相关产品推荐
相关产品推荐

