如何实现点击可点击式popover外部时使其自动隐藏
Bootstrap 5 Popover点击外部无法隐藏的解决方法
问题说明
我实现了一个包含跳转链接的Bootstrap 5 Popover,点击触发图标可以正常显示,但点击Popover外部区域时,无法自动隐藏Popover。相关代码如下:
Popover HTML代码
<i class="bi bi-question-circle text-primary float-right" data-bs-toggle="popover" data-bs-content="{{$accountTypeQuestionMark[$value] ? $accountTypeQuestionMark[$value]:''}}" data-bs-trigger="click" data-bs-html="true"> </i>
初始化JavaScript代码
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/js/bootstrap.bundle.min.js"></script> <script> var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]')) var popoverList = popoverTriggerList.map(function (popoverTriggerEl) { return new bootstrap.Popover(popoverTriggerEl) }) </script>
尝试过的无效代码
$(document).on('click', function (e) { $('[data-bs-toggle="popover"]').each(function () { if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) { $(this).popover('hide'); } }); });
问题原因
- 配置的
data-bs-trigger="click"仅绑定了点击触发元素的切换逻辑,Bootstrap 5默认不会监听外部点击来关闭Popover。 - 尝试的jQuery代码基于旧版Bootstrap的API,而Bootstrap 5已完全移除jQuery依赖,无法通过
$(element).popover('hide')这种方式调用实例方法。
解决方案
方案一:利用Bootstrap原生触发属性(简单高效)
修改Popover的触发方式为click focus,同时给触发元素添加tabindex="0"使其支持聚焦,这样点击外部区域或按下ESC键都能自动关闭Popover:
<i class="bi bi-question-circle text-primary float-right" data-bs-toggle="popover" data-bs-content="{{$accountTypeQuestionMark[$value] ? $accountTypeQuestionMark[$value]:''}}" data-bs-trigger="click focus" data-bs-html="true" tabindex="0"> </i>
方案二:纯JavaScript监听全局点击事件(自定义程度高)
通过Bootstrap 5官方的实例方法获取Popover实例,手动判断点击区域并关闭:
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/js/bootstrap.bundle.min.js"></script> <script> // 初始化所有Popover const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]'); const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl)); // 监听全局点击事件 document.addEventListener('click', function(e) { popoverTriggerList.forEach(triggerEl => { const popoverInstance = bootstrap.Popover.getInstance(triggerEl); // 判断点击目标既不是触发元素,也不在Popover内容区域内 if (!triggerEl.contains(e.target) && !(popoverInstance?._popover?.contains(e.target))) { popoverInstance?.hide(); } }); }); </script>
内容的提问来源于stack exchange,提问作者kinan
相关产品推荐
相关产品推荐

