web-dev-qa-db-ja.com

Twitter bootstrap 2.3.2ポップオーバーはホバリング中も開いたままです

マウスがトリガーを離れるとすぐに消えるデフォルトのポップオーバーよりも少し寛容になりたいボトム指向のポップオーバーがあります。

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

マウスがトリガーまたはポップオーバーコンテンツの上にある限り、開いたままにしておきますが、トリガー要素からコンテンツへの矢印にマウスを移動する必要があるため、ユーザーにとっては困難です。ポップオーバーと対話するために。 2つの解決策を念頭に置いて、どちらも機能していません。

1)遅延オプションはこれを行う必要があります。ポップオーバー呼び出しにdelay: {hide: 500}を追加すると、マウスが離れた後もポップオーバーは開いたままになりますが、トリガー要素またはポップオーバーが消える前に再入力しても、bootstrapはポップオーバーを開いたままにするように指示されません、したがって、最初のタイムアウトの終わりに消えます。

2)矢印の包含要素を広げて、トリガー要素から背景へ、トリガー要素とポップオーバーからポップオーバーの間を移動するマウスが機能するようにします(マウスがトリガー/要素から離れることはありません)。以下は、矢印がCSSの境界線を重ねて描画されることを除いて機能するため、背景は透明ではありません。 http://jsfiddle.net/HAZS8/

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

回避策は、mouseoverイベントとmouseleaveイベントをjqueryでハードワイヤードするか、重複する境界線の矢印を画像に置き換えることです。より良い修正?

18
user941238

ポップオーバーのshowおよびhideイベントを処理できます。

$('#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/

それはそこのように内蔵されたポップオーバーのためにあなたがしたい機能のために何もしていないようですので、これは私が思い付いたものです:)

ポップオーバーが実際に隠されているか、実際に表示されている場合 - どのようなナイスだと、それだけで彼らが本当に必要がある場合はハンドラを実行することを可能にするということです。また、ポップオーバーの各インスタンスは互いに一意であるため、グローバルなトリックは発生しません。

19
Ian

私はこれを解決するためのより一般的なアプローチを持っており、それを自分で使用しています。これには、ポップオーバーの非表示関数のオーバーロード、関連するツールチップがホバーされているかどうかの確認、および適切な反応が含まれます。イベント処理と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&jQueryソースの後にこれをロードします。

32
kevin