【问题标题】:How do I destroy all instances of Bootstrap Popover?如何销毁 Bootstrap Popover 的所有实例?
【发布时间】:2015-01-02 08:11:02
【问题描述】:

我有一个使用 Backbone 的单页应用程序,每当我翻过某些东西然后单击“返回”按钮时,弹出框就会永远存在。

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

【问题讨论】:

    标签: javascript html twitter-bootstrap backbone.js


    【解决方案1】:

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

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

    如果您需要或愿意,也可以使用destroy

    挑战在于处理那些动态创建的弹出框。

    用弹出框标记元素

    我会实现这样的东西。我会覆盖默认的 popover 方法,并且我会尝试尽早执行此覆盖,以便需要弹出框的 everything 使用我的覆盖。它所做的只是标记使用带有类的弹出框的元素。 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 的页面,则上述方法起作用。 (是的,这是可能的。)我在我的一个应用程序中使用类似的东西来处理工具提示,所以我知道这个原则是合理的。碰巧在我的应用程序中,所有工具提示都是由我的代码创建的,因此没有丢失某些内容的风险。

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

    如果您处于可以创建弹出框而不被标记的情况(我称之为“逃生者”),那么您需要查询整个 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');
    });
    

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

    概念证明

    这里有一个fiddle 说明了整个事情:

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

    • “Add an Escapee”模拟会添加弹出框并设法使用原始 Bootstrap 代码的代码。

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

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

    【讨论】:

    • 这个答案真的很好。如果您使用 fullcalendar.js 并向事件添加弹出框,您实际上可以遍历所有具有 .fc-event 的元素并使用 all 元素方法来隐藏弹出框。这样您就不必循环文档中的所有元素。您实际上可以使用var popover = $.data(this, "bs.popover"); popover.hide(); 隐藏弹出框
    • btw: $(".popover").popover("destroy") 是一个异步调用,需要几毫秒(也许这个信息是给重要的人的)
    【解决方案2】:

    试试这个:

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

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

    【讨论】:

      【解决方案3】:

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

      您可以查看documentation 以获取更多 popover() 的选项和参数。

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

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

      以上代码将销毁页面中的所有弹出框。所以代替这个,使用类选择器。

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

      【讨论】:

        【解决方案4】:

        如果您有问题并且需要确定全部删除:

        $('.popover').remove();
        

        会有所帮助(Popover 会自动添加此类,即使对于动态创建的对象也是如此)。它破坏了所有的popover DOM-Object,包括。回调等 但这是粗略的方式。通常我会通过 popover 类(干净的方式)释放所有内容,并确保我在之后进行硬清理。很适合我!

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

        如果您想删除所有 execpt 之一,请使用带有 :not-Selector 的 filter()

        $('.popover').filter(':not(#yourID)').popover('dispose');
        $('.popover').filter(':not(#yourID)').remove();
        

        popover 还添加了一个带有随机数的 id

        #popoverxxxxx where xxxxx is a five digit number.
        

        这有时有助于比较弹出框。当然,这也可以用来识别弹出框。

        【讨论】:

          【解决方案5】:

          这样的通用方法(假设您使用数据绑定)应该可以解决问题:

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

          或更极端的称呼

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

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

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

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

          【讨论】:

            【解决方案6】:

            你可以使用这个hide all popovers:

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

            你可以使用这个destroy all popovers:

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

            hidedestory 之间的区别在于,当您 hide 弹出窗口时,您不需要 响应它,但是当您 销毁做的

            查看我的JSFIDDLE,然后:

            • 单击所有弹出框,然后单击hide。点击hide 后,您可以再次点击弹出框。

            • 单击所有弹出框,然后单击destroy。单击destroy 后,再次尝试单击弹出框并查看什么都不会发生,因为它们已被销毁
              为了使它们再次发挥作用,您需要点击reactive,然后尝试。

            【讨论】:

              【解决方案7】:

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2013-08-02
                • 1970-01-01
                • 1970-01-01
                • 2016-11-29
                • 2014-10-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多