Javascript 如何销毁 Bootstrap Popover 的所有实例?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26768991/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 23:21:01  来源:igfitidea点击:

How do I destroy all instances of Bootstrap Popover?

javascripthtmltwitter-bootstrapbackbone.js

提问by TIMEX

I have a single page app using Backbone, and whenever I over over something and then click the "back" button, the popover forever stays.

我有一个使用 Backbone 的单页应用程序,每当我越过某物然后单击“后退”按钮时,弹出框就会永远保留。

I want to destroy all instances of popover when a new instance is loaded.

我想在加载新实例时销毁所有 popover 实例。

回答by Louis

Finding the popovers that are created through the data API is not difficult and has been covered in other answers like those of David Mulder and Amir Popovich. You just do:

查找通过数据 API 创建的弹出窗口并不困难,并且已在其他答案中进行了介绍,例如 David Mulder 和 Amir Popovich 的答案。你只需要:

$("[data-toggle='popover']").popover('hide');

Or you can use destroyif you need to or prefer to.

或者您可以destroy根据需要或喜欢使用。

The challenge is to handle those popovers that are created dynamically.

挑战在于处理那些动态创建的弹出窗口

Marking the Elements with Popovers

用弹出框标记元素

I would implement something like this. I'd override the default popovermethod and I'd try to perform this override as early as possible so that everythingthat needs a popover uses my override. What it does is just mark elements that use a popover with a class. Bootstrap does not mark them itself:

我会实施这样的事情。我会覆盖默认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;

Then to clear everything before the unloading, I'd put in the code that detects the unloading the following:

然后为了在卸载之前清除所有内容,我将放入检测卸载的代码如下:

$(".marked-as-having-a-popover").popover('hide');

Or it could use destroyrather than hideif testing shows that it works better for your use-case.

或者它可以使用destroy而不是hide测试表明它更适合您的用例。

Now, the method above willwork if the override happens early enough and you do not have a page where multiple jQueries are loaded. (Yep, this is possible.) I use something similar to deal with tooltips in one of my applications so I know the principle is sound. It so happens that in my app, all tooltips are created by my code so there is no risk of missing something.

现在,如果覆盖发生得足够早并且您没有加载多个 jQueries 的页面,则上述方法起作用。(是的,这是可能的。)我在我的一个应用程序中使用类似的东西来处理工具提示,所以我知道这个原则是合理的。碰巧在我的应用程序中,所有工具提示都是由我的代码创建的,因此没有遗漏某些东西的风险。

Finding All Elements with Popovers, Even Unmarked

查找所有带有弹出框的元素,甚至是未标记的元素

If you are in a situation where a popover can be created without being marked (I call this an "escapee"), then you need to query the whole DOM and find which elements have popovers. There is no shortcut here. You cannot rely on attributes like data-contentbecause popovers can be created wholly dynamically (i.e. without any of the data-attributes). Also, all kinds of elements can get popovers, so you cannot reliably assume that only buttonelements will have a popover. The only surefire way to find everything that needs handling is to look at each element in the DOM and check whether it has a popover:

如果您处于无需标记即可创建弹出窗口的情况(我称其为“逃生者”),那么您需要查询整个 DOM 并找到哪些元素具有弹出窗口。这里没有捷径。您不能依赖属性,data-content因为可以完全动态地创建弹出窗口(即没有任何data-属性)。此外,所有类型的元素都可以获得弹出框,因此您不能可靠地假设只有button元素会有弹出框。找到需要处理的所有内容的唯一可靠方法是查看 DOM 中的每个元素并检查它是否有弹出框:

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

Again, destroycould be used rather than hide.

同样,destroy可以使用而不是hide.

Proof of Concept

概念证明

Here is a fiddlethat illustrates the entire thing:

这是一个说明整个事情的小提琴

  • "Add a Dynamic Popover" simulates code that would add a popover when the override is in effect.

  • "Add an Escapee" simulates code that would add a popover and somehow manage to use the original Bootstrap code.

  • "Clear Marked" clears only the marked popovers.

  • "Clear All" clears every single popover marked or not.

  • “添加动态弹出框”模拟在覆盖生效时添加弹出框的代码。

  • “Add an Escapee”模拟了添加弹出框的代码,并以某种方式设法使用原始的 Bootstrap 代码。

  • “清除标记”仅清除标记的弹出框。

  • “全部清除”清除每个标记或未标记的弹出窗口。

回答by Laxmikant Dange

Its very simple, just you have to call one function popover() with argument "destroy" to destroy the popover. It will destroy all popovers which is created by $("[data-toggle=popover]").popover();

它非常简单,只需要调用一个带有参数“destroy”的函数 popover() 来销毁弹出窗口。它将销毁所有由 $("[data-toggle=popover]").popover(); 创建的弹出框。

you can check documentationfor more options and arguments of popover().

您可以查看文档以了解 popover() 的更多选项和参数。

I suggest you to destroy popovers with having specific class name instead of using following code.

我建议您使用特定的类名而不是使用以下代码来销毁弹出窗口。

$("[data-toggle='popover']").popover('destroy');

The above code will destroy all popovers in the page. So instead of this, use class selector.

上面的代码将销毁页面中的所有弹出窗口。因此,不要使用类选择器。

$(".YourClassName").popover('destroy');

回答by Samuel Vicent

try with this:

试试这个:

$('YOUR_ELEMENT_SELECTOR').popover('dispose');

$('YOUR_ELEMENT_SELECTOR').popover('dispose');

reference url: https://getbootstrap.com/docs/4.1/components/popovers/

参考网址:https: //getbootstrap.com/docs/4.1/components/popovers/

回答by David Mulder

Something generic like this (assuming you're using data-bindings) should do the trick:

像这样的通用内容(假设您正在使用数据绑定)应该可以解决问题:

$('[data-toggle="popover"]').popover('hide')

or the more extreme call

或者更极端的呼唤

$('[data-toggle="popover"]').popover('destroy')

though I doubt that would make sense often. Still to address the specific bug you're encountering you should create a minimal test case so that that bug itself can be addressed.

虽然我怀疑这是否经常有意义。仍然要解决您遇到的特定错误,您应该创建一个最小的测试用例,以便可以解决该错误本身。

Oh and if you specifically want to check for open popovers you can use .data("bs.popover").$tip.parent().length(which is a bit of an hack), for example:

哦,如果你特别想检查你可以使用的打开的弹出窗口.data("bs.popover").$tip.parent().length(这有点黑客),例如:

$('[data-toggle="popover"]:eq(0)').data("bs.popover").$tip.parent().length == 1

回答by Amir Popovich

You can hideall popovers by using this:

你可以hide使用这个来弹出所有的弹出框:

$("[data-toggle='popover']").popover('hide');

You can destroyall popovers by using this:

你可以destroy使用这个来弹出所有的弹出框:

$("[data-toggle='popover']").popover('destroy');

The difference between hideand destoryis that when you hidea popover you do not needto reactiveit, but when you destroyit you do.

hide和之间的区别在于destory,当您hide弹出一个弹出框时,您不需要对其进行反应,但是当您销毁它时,您会这样做

Check out my JSFIDDLEand then:

查看我的JSFIDDLE然后:

  • Click on all popovers and then click hide. After clicking hideyou canclick on the popovers again.

  • Click on all popovers and then click destroy. After clicking destroytry clicking on the popovers again and see that nothing will happensince they are destroyed.
    In order to make them functional again, you will need to click on reactiveand then try.

  • 单击所有弹出窗口,然后单击hide。单击后,hide可以再次单击弹出窗口。

  • 单击所有弹出窗口,然后单击destroy。单击后destroy,再次尝试单击弹出窗口,看到它们被销毁后不会发生任何事情。为了使它们再次发挥作用,您需要单击“ reactive”然后尝试。

回答by Romain

Popovers must be initialized manually, so you know exactly what you have to destroy because you did initialize it. You should just call the destroy function with the same selector. Or maybe I am missing something ?

Popovers 必须手动初始化,所以你确切地知道你必须销毁什么,因为你确实初始化了它。您应该使用相同的选择器调用 destroy 函数。或者也许我错过了什么?