如何销毁Bootstrap Popover的所有实例
How do I destroy all instances of Bootstrap Popover?
我有一个使用Backbone的单页应用程序,每当我浏览某个内容,然后单击"返回"按钮时,弹出窗口就会永远保留。
我想在加载新实例时销毁popover的所有实例。
找到通过数据API创建的弹出窗口并不困难,其他答案也涵盖了这一点,如David Mulder和Amir Popovich的答案。你只需要:
$("[data-toggle='popover']").popover('hide');
或者,如果您需要或喜欢,也可以使用destroy
。
挑战在于处理那些动态创建的弹出窗口
用弹出框标记元素
我会实现这样的东西。我会覆盖默认的popover
方法,并尝试尽早执行此覆盖,以便所有需要popover的都使用我的覆盖。它所做的只是用类标记使用popover的元素。Bootstrap本身不标记它们:
// Override popover so as to mark everything that uses a popover.
var old_popover = $.fn.popover;
function my_popover() {
this.addClass('marked-as-having-a-popover');
return old_popover.apply(this, arguments);
}
$.fn.popover = my_popover;
然后,为了在卸载前清除所有内容,我会输入检测卸载的代码如下:
$(".marked-as-having-a-popover").popover('hide');
或者,如果测试表明它更适合您的用例,它可以使用destroy
而不是hide
。
现在,如果覆盖发生得足够早,并且您没有加载多个jQueries的页面,则上面的方法将工作。(是的,这是可能的。)我在一个应用程序中使用了类似的东西来处理工具提示,所以我知道原理是正确的。碰巧在我的应用程序中,所有工具提示都是由我的代码创建的,所以没有丢失东西的风险。
查找具有弹出窗口的所有元素,甚至是未标记的元素
如果您所处的情况是,可以在不标记的情况下创建popover(我称之为"escapee"),那么您需要查询整个DOM并找到哪些元素具有popover。这里没有捷径。您不能依赖像data-content
这样的属性,因为popover可以完全动态地创建(即没有任何data-
属性)。此外,所有类型的元素都可以得到popover,因此不能可靠地假设只有button
元素会有popover。找到所有需要处理的东西的唯一可靠方法是查看DOM中的每个元素,并检查它是否有popover:
// Obviously this is quite expensive but in a situation where there *can* be escapees
// then you have to check all elements to see if they have a popover.
$("*").each(function () {
// Bootstrap sets a data field with key `bs.popover` on elements that have a popover.
// Note that there is no corresponding **HTML attribute** on the elements so we cannot
// perform a search by attribute.
var popover = $.data(this, "bs.popover");
if (popover)
$(this).popover('hide');
});
同样,可以使用destroy
而不是hide
。
概念证明
这是一把小提琴,说明了整个事情:
"添加动态Popover"模拟在覆盖生效时添加Popover的代码。
"添加Escapee"模拟了添加popover并以某种方式使用原始Bootstrap代码的代码。
"清除标记"仅清除标记的弹出窗口。
"全部清除"清除所有标记或未标记的弹出窗口。
尝试使用以下方法:
$('YOUR_ELEMENT_SELECTOR').popover('dispose');
引用url:https://getbootstrap.com/docs/4.1/components/popovers/
它非常简单,只需调用一个带有参数"destroy"的函数popover()即可销毁popover。它将销毁由$("[data toggle=popover]")创建的所有popover();
您可以查看文档以了解popover()的更多选项和参数。
我建议您销毁具有特定类名的popover,而不是使用以下代码。
$("[data-toggle='popover']").popover('destroy');
上面的代码将销毁页面中的所有弹出窗口。因此,使用类选择器来代替此操作。
$(".YourClassName").popover('destroy');
如果您有问题,需要删除所有内容:
$('.popover').remove();
将有所帮助(Popover自动添加此类,即使是动态创建的对象)。它破坏了所有popover DOM对象,包括回调等。但这是一条艰难的道路。通常情况下,我会对popover类(干净的方式)感到不快,当然之后我会做一次艰难的清理。对我来说很好!
$('.popover').popover('dispose');
$('.popover').remove();
如果您想删除所有execpt one,请使用filter()和:not Selector
$('.popover').filter(':not(#yourID)').popover('dispose');
$('.popover').filter(':not(#yourID)').remove();
popover还添加了一个带有随机数的id
#popoverxxxxx where xxxxx is a five digit number.
这有时有助于比较popover。当然,这也可以用来识别弹出窗口。
$('[data-toggle="popover"]').popover('hide')
或者更极端的呼叫
$('[data-toggle="popover"]').popover('destroy')
尽管我经常怀疑这是否合理。仍然要解决您遇到的特定bug,您应该创建一个最小的测试用例,以便能够解决该bug本身。
哦,如果你特别想检查打开的弹出窗口,你可以使用.data("bs.popover").$tip.parent().length
(这有点像黑客),例如:
$('[data-toggle="popover"]:eq(0)').data("bs.popover").$tip.parent().length == 1
您可以使用以下方法hide
所有弹出窗口:
$("[data-toggle='popover']").popover('hide');
您可以使用以下内容destroy
所有弹出窗口:
$("[data-toggle='popover']").popover('destroy');
hide
和destory
之间的区别在于,当hide
弹出时,不需要来反应,但当破坏时,会。
查看我的JSFIDDLE
,然后:
单击所有弹出窗口,然后单击
hide
。单击hide
后,可以再次单击弹出窗口。单击所有弹出窗口,然后单击
destroy
。单击destroy
后,再次尝试单击弹出窗口,并查看不会发生任何事情,因为它们被破坏
为了使它们再次发挥作用,您需要单击反应,然后尝试。
必须手动初始化Popovers,这样您就可以确切地知道要销毁什么,因为您已经初始化了它。您应该使用相同的选择器来调用destroy函数。或者我错过了什么?
- ES6构造函数返回基类的实例
- KnockoutJS-组件-多个实例
- 为什么无法在TypeScript中导出类实例
- 如何在GoogleWeb工具包(GWT)中从JSNI调用接口(实例化)
- fluxxor向一个flux实例添加一组以上的操作
- 使用jQuery获取Dropzone实例/对象
- "实例范围”;TypeScript类的getter/setter
- 如何在速度模板中获取LiferayPortlet实例id
- 同一项怎么可能在一个实例中未定义,却在另一个实例上定义
- 实例创建(JS)
- 显示模块模式在Knockout中设置模型的新实例
- 如何获取单选按钮的多个实例的选定单选按钮值
- 当同一浏览器的两个实例浏览时,Javascript页面如何具有唯一的ID
- 在哪里可以找到RXUI Javascript'时间飞逝'实例
- spine.js在启动时填充模型实例
- 不再需要时使用jQuery/kill实例
- 如何在用户输入时实例化数组
- 从Sequelize中的非实例更新
- 如何基于数组值创建新实例
- 如何销毁Bootstrap Popover的所有实例