18

我有一个面向底部的弹出框,我希望它比默认弹出框更宽容,一旦鼠标离开触发器,默认弹出框就会消失。

$('#example').popover({
  html: true,
  trigger: 'hover',
  container: '#example',
  placement: 'bottom',
  content: function () {
      return '<div class="box">here is some content</div>';
  }
});

只要鼠标悬停在触发器或弹出内容上,我就让它保持打开状态,但这对用户来说很难,因为他们必须在不离开这些区域的情况下从触发器元素到箭头再到内容为了与弹出框交互。有两种解决方案,但都不起作用:

1)延迟选项应该这样做。添加 delay: {hide: 500} 到 popover 调用后,popover 会在鼠标离开后打开,但在它消失之前重新进入 trigger elem 或 popover 并不会告诉 bootstrap 保持 popover 打开,因此在初始超时结束时消失。

2)加宽箭头的包含元素,以便鼠标从触发元素到触发元素之间的背景和弹出框到弹出框的工作(然后鼠标永远不会离开触发器/元素)。以下作品除了箭头是用重叠的 CSS 边框绘制的,所以背景不透明:http: //jsfiddle.net/HAZS8/

.popover.bottom .arrow {
    left: 0%;
    padding-left:50%;
    padding-right:50%;
}

解决方法是用 jquery 硬连线 mouseover 和 mouseleave 事件,或者用图像替换重叠边框箭头。更好的修复?

4

2 回答 2

32

我有一种更通用的方法来解决这个问题,我自己正在使用它。它涉及重载弹出框的隐藏功能,检查相关的工具提示是否被悬停,并做出适当的反应 - 而不是添加所有事件处理和 html5 数据设置。

(function($) {

    var oldHide = $.fn.popover.Constructor.prototype.hide;

    $.fn.popover.Constructor.prototype.hide = function() {
        if (this.options.trigger === "hover" && this.tip().is(":hover")) {
            var that = this;
            // try again after what would have been the delay
            setTimeout(function() {
                return that.hide.call(that, arguments);
            }, that.options.delay.hide);
            return;
        }
        oldHide.call(this, arguments);
    };

})(jQuery);

在您的引导程序和 jQuery 源代码之后加载它。

于 2013-11-06T05:32:08.870 回答
19

您可以处理弹出框的showhide事件:

$('#example').popover({
    html: true,
    trigger: 'hover',
    container: '#example',
    placement: 'bottom',
    content: function () {
        return '<div class="box">here is some content</div>';
    },
    animation: false
}).on({
    show: function (e) {
        var $this = $(this);

        // Currently hovering popover
        $this.data("hoveringPopover", true);

        // If it's still waiting to determine if it can be hovered, don't allow other handlers
        if ($this.data("waitingForPopoverTO")) {
            e.stopImmediatePropagation();
        }
    },
    hide: function (e) {
        var $this = $(this);

        // If timeout was reached, allow hide to occur
        if ($this.data("forceHidePopover")) {
            $this.data("forceHidePopover", false);
            return true;
        }

        // Prevent other `hide` handlers from executing
        e.stopImmediatePropagation();

        // Reset timeout checker
        clearTimeout($this.data("popoverTO"));

        // No longer hovering popover
        $this.data("hoveringPopover", false);

        // Flag for `show` event
        $this.data("waitingForPopoverTO", true);

        // In 1500ms, check to see if the popover is still not being hovered
        $this.data("popoverTO", setTimeout(function () {
            // If not being hovered, force the hide
            if (!$this.data("hoveringPopover")) {
                $this.data("forceHidePopover", true);
                $this.data("waitingForPopoverTO", false);
                $this.popover("hide");
            }
        }, 1500));

        // Stop default behavior
        return false;
    }
});

演示:http: //jsfiddle.net/L4Hc2/

弹出框似乎没有内置任何您想要的功能,所以这就是我想出的:)

好的是它只允许处理程序在它们确实应该执行的情况下执行 - 如果弹出框实际上被隐藏或实际显示。此外,popover 的每个实例彼此都是唯一的,因此不会发生全局诡计。

于 2013-05-24T18:29:29.923 回答