Twitter引导程序2.3.2 popover在悬停时保持打开状态

时间:2013-05-24 17:02:06

标签: javascript css twitter-bootstrap popover twitter-bootstrap-2

我有一个以底部为导向的弹出窗口,我想比默认弹出窗口更宽容,一旦鼠标离开触发器就会消失。

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

只要鼠标悬停在触发器或弹出窗口内容上,我就可以保持打开状态,但这对用户来说很难,因为他们必须将鼠标从触发元素移动到箭头到内容离开这些区域以便与popover互动。考虑两种解决方案,两种解决方案都不起作用:

1)延迟选项应该这样做。加入     delay: {hide: 500} 鼠标离开后弹出窗口中的popover会打开,但是在它消失之前重新进入触发器elem或popover不会告诉bootstrap保持弹出窗口打开,所以在初始超时结束时消失。

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

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

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

2 个答案:

答案 0 :(得分:32)

我有一个更通用的方法来解决这个问题,我正在使用它。它涉及重载popover的hide函数,检查相关的工具提示是否正在盘旋,并做出适当的反应 - 而不是添加所有的事件处理&amp; 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);

在你的bootstrap&amp;之后加载它jQuery来源。

答案 1 :(得分:19)

您可以处理popover的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;
    }
});

DEMO: http://jsfiddle.net/L4Hc2/

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

唯一的好处是它只允许处理程序执行,如果它们确实应该执行 - 如果popover实际上是隐藏的或实际显示的话。此外,弹出窗口的每个实例彼此都是唯一的,因此没有全局欺骗。