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

TIM*_*MEX 9 html javascript backbone.js twitter-bootstrap

我有一个使用Backbone的单页应用程序,每当我翻过某些东西然后单击"后退"按钮时,弹出窗口永远保持不变.

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

Lou*_*uis 23

查找通过数据API创建的弹出窗口并不困难,并且已经在David Mulder和Amir Popovich等其他答案中得到了解决.你这样做:

$("[data-toggle='popover']").popover('hide');
Run Code Online (Sandbox Code Playgroud)

或者你可以使用,destroy如果你需要或喜欢.

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

用弹出框标记元素

我会实现这样的事情.我会覆盖默认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;
Run Code Online (Sandbox Code Playgroud)

然后在卸载之前清除所有内容,我会输入检测卸载以下内容的代码:

$(".marked-as-having-a-popover").popover('hide');
Run Code Online (Sandbox Code Playgroud)

或者它可以使用destroy而不是hide测试显示它对您的用例更好.

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

使用弹出窗口找到所有元素,甚至没有标记

如果您处于可以创建弹出窗口但未标记的情况下(我将其称为"escapee"),那么您需要查询整个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');
});
Run Code Online (Sandbox Code Playgroud)

再次,destroy可以使用而不是hide.

概念证明

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

  • "添加动态弹出窗口"模拟在覆盖生效时添加弹出窗口的代码.

  • "添加一个Escapee"模拟将添加一个popover并以某种方式设法使用原始Bootstrap代码的代码.

  • "Clear Marked"仅清除标记的popovers.

  • "全部清除"清除每个标记或不标记的弹出窗口.

  • 顺便说一句:$(".popover").popover("destroy") 是一个异步调用,需要几毫秒(也许这个信息是给重要的人的) (2认同)