How to destroy all instances of Bootstrap Popover?

I have a one-page application using Backbone, and whenever I rewrite something and then press the back button, a popover remains forever.

I want to destroy all popover instances when loading a new instance.

+6
source share
5 answers

Finding popovers created using the data API is straightforward and has been addressed in other answers such as David Mulder and Amir Popovich. You just do:

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

Or you can use destroy if you need or prefer.

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

Labeling Items Using Popovers

I would do something like this. I would override the default popover , and I will try to do this override as early as possible so that everything that requires popover uses my override. What he does is just label elements that use popover with the class. Bootstrap does not label them themselves:

 // 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 unloading, I added code that detects the unloading of the following:

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

Or it can use destroy , rather than hide , if testing shows that it works better for your use case.

Now the method above will work if the redefinition happens early enough and you donโ€™t have a page where several jQueries load. (Yes, thatโ€™s possible.) Iโ€™m using something like tooltips in one of my applications, so I know the principle sounds. It so happened that in my application all the tooltips are created by my code, so there is no risk of missing something.

Search for all items using Popovers, not even checked

If you are in a situation where a popover can be created without marking (I call it "escapee"), you need to query the entire DOM and find which elements have popovers. There is no shortcut. You cannot rely on attributes like data-content , because popovers can be created completely dynamically (i.e. without any data- attributes). In addition, all element types can receive popovers, so you cannot reliably assume that only button elements will have a popover. The only sure way to find everything that needs processing is to look at each element in the DOM and check if it has a 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'); }); 

Again, destroy can be used, not hide .

Proof of concept

Here is a fiddle that illustrates everything:

  • "Add Dynamic Popover" mimics the code that popover will add when redefinition takes effect.

  • "Add Escapee" mimics the code that will add a popover and somehow manage to use the Bootstrap source code.

  • "Clear Marked" clears only marked popovers.

  • Clear All clears marked or missing marks.

+18
source

Something in common similar to this (if you use data bindings) should do the trick:

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

or more extreme challenge

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

although I doubt it will make sense often. To solve the specific error you are encountering, you must create a minimal test case so that this error can be resolved.

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

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

You can hide pop up using this:

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

You can destroy pop up using this:

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

The difference between hide and destory is that when you hide you do not like to respond , but when you destroy , you do it .

Check out JSFIDDLE and then:

  • Click on all popovers, and then click hide . After clicking hide you can click on popovers again.

  • Click on all popovers, and then click destroy . After clicking destroy try clicking popovers again and see that nothing happens because they are destroyed .
    To make them functional again, you will need to press react and then try.

0
source

The fellow travelers must be initialized manually, so you know exactly what you need to destroy, because you initialized it. You should just call the destroy function with the same selector. Or maybe I'm missing something?

0
source

It is very simple, you just need to call one popover () function with the destroy argument to destroy the popover. It will destroy all popovers that are created using $ ("[data-toggle = popover]"). Popover ();

you can check the documentation for more options and arguments for popover ().

I suggest you kill popovers with a specific class name instead of using the following code.

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

The above code will destroy all the popovers on the page. So use the class selector instead.

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

Source: https://habr.com/ru/post/977795/


All Articles