304

モーダルと同じ方法でポップオーバーを閉じられるようにすることはできますか。ユーザーがそれらの外側のどこかをクリックしたときにそれらを閉じますか?

残念ながら、ポップオーバーの代わりに実際のモーダルを使用することはできません。モーダルは position:fixed を意味し、もはやポップオーバーではないからです。:(

4

41 に答える 41

480

更新:もう少し堅牢なソリューション: http://jsfiddle.net/mattdlockyer/C5GBU/72/

テキストのみを含むボタンの場合:

$('body').on('click', function (e) {
    //did not click a popover toggle or popover
    if ($(e.target).data('toggle') !== 'popover'
        && $(e.target).parents('.popover.in').length === 0) { 
        $('[data-toggle="popover"]').popover('hide');
    }
});

アイコンを含むボタンの使用(このコードには Bootstrap 3.3.6 のバグがあります。この回答の以下の修正を参照してください)

$('body').on('click', function (e) {
        //did not click a popover toggle, or icon in popover toggle, or popover
        if ($(e.target).data('toggle') !== 'popover'
            && $(e.target).parents('[data-toggle="popover"]').length === 0
            && $(e.target).parents('.popover.in').length === 0) { 
            $('[data-toggle="popover"]').popover('hide');
        }
    });

JS で生成されたポップオーバー'[data-original-title]'の場合'[data-toggle="popover"]'

警告:上記の解決策では、複数のポップオーバーを一度に開くことができます。

一度に 1 つのポップオーバーをしてください:

更新:ブートストラップ 3.0.x、コードまたはフィドルhttp://jsfiddle.net/mattdlockyer/C5GBU/2/を参照

$('body').on('click', function (e) {
    $('[data-toggle="popover"]').each(function () {
        //the 'is' for buttons that trigger popups
        //the 'has' for icons within a button that triggers a popup
        if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
            $(this).popover('hide');
        }
    });
});

これは、すでに開いていてクリックされていない、またはリンクがクリックされていないポップオーバーを閉じる処理を行います。


更新: Bootstrap 3.3.6、フィドルを参照

閉じた後、再度開くのに 2 回のクリックが必要になる問題を修正

$(document).on('click', function (e) {
    $('[data-toggle="popover"],[data-original-title]').each(function () {
        //the 'is' for buttons that trigger popups
        //the 'has' for icons within a button that triggers a popup
        if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {                
            (($(this).popover('hide').data('bs.popover')||{}).inState||{}).click = false  // fix for BS 3.3.6
        }

    });
});

更新:以前の改善の条件を使用して、このソリューションが達成されました。ダブルクリックとゴースト ポップオーバーの問題を修正します。

$(document).on("shown.bs.popover",'[data-toggle="popover"]', function(){
    $(this).attr('someattr','1');
});
$(document).on("hidden.bs.popover",'[data-toggle="popover"]', function(){
    $(this).attr('someattr','0');
});
$(document).on('click', function (e) {
    $('[data-toggle="popover"],[data-original-title]').each(function () {
        //the 'is' for buttons that trigger popups
        //the 'has' for icons within a button that triggers a popup
        if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
            if($(this).attr('someattr')=="1"){
                $(this).popover("toggle");
            }
        }
    });
});
于 2013-02-13T15:45:27.790 に答える
84
$('html').on('mouseup', function(e) {
    if(!$(e.target).closest('.popover').length) {
        $('.popover').each(function(){
            $(this.previousSibling).popover('hide');
        });
    }
});

ポップオーバー以外の場所をクリックすると、すべてのポップオーバーが閉じます

ブートストラップ 4.1 の更新

$("html").on("mouseup", function (e) {
    var l = $(e.target);
    if (l[0].className.indexOf("popover") == -1) {
        $(".popover").each(function () {
            $(this).popover("hide");
        });
    }
});
于 2013-03-27T21:50:27.563 に答える
43

最もシンプルで最もフェイル セーフなバージョンで、どのブートストラップ バージョンでも動作します。

デモ: http://jsfiddle.net/guya/24mmM/

デモ 2: ポップオーバー コンテンツ内をクリックしても閉じない http://jsfiddle.net/guya/fjZja/

デモ 3: 複数のポップオーバー: http://jsfiddle.net/guya/6YCjW/


この行を呼び出すだけで、すべてのポップオーバーが閉じられます。

$('[data-original-title]').popover('hide');

次のコードで外側をクリックすると、すべてのポップオーバーが閉じられます。

$('html').on('click', function(e) {
  if (typeof $(e.target).data('original-title') == 'undefined') {
    $('[data-original-title]').popover('hide');
  }
});

上記のスニペットは、本文にクリック イベントを追加します。ユーザーがポップオーバーをクリックすると、通常どおりに動作します。ユーザーがポップオーバーではないものをクリックすると、すべてのポップオーバーが閉じます。

動作しない他の例とは対照的に、Javascript で開始されるポップオーバーでも動作します。(デモを見る)

ポップオーバー コンテンツ内をクリックしたときに閉じたくない場合は、次のコードを使用します (2 番目のデモへのリンクを参照)。

$('html').on('click', function(e) {
  if (typeof $(e.target).data('original-title') == 'undefined' && !$(e.target).parents().is('.popover.in')) {
    $('[data-original-title]').popover('hide');
  }
});
于 2013-10-28T15:01:45.313 に答える
19

想定される高投票のソリューションはどれも、私にとって正しく機能しませんでした。(他の要素をクリックして) ポップオーバーを初めて開いて閉じた後、トリガー リンクを 1 回ではなく2回クリックするまで、ポップオーバーが再び開かない場合、それぞれがバグにつながります。

だから私はそれを少し修正しました:

$(document).on('click', function (e) {
    var
        $popover,
        $target = $(e.target);

    //do nothing if there was a click on popover content
    if ($target.hasClass('popover') || $target.closest('.popover').length) {
        return;
    }

    $('[data-toggle="popover"]').each(function () {
        $popover = $(this);

        if (!$popover.is(e.target) &&
            $popover.has(e.target).length === 0 &&
            $('.popover').has(e.target).length === 0)
        {
            $popover.popover('hide');
        } else {
            //fixes issue described above
            $popover.popover('toggle');
        }
    });
})
于 2015-11-27T08:43:06.653 に答える
18

これは基本的にそれほど複雑ではありませんが、グリッチを回避するために行うべきいくつかのチェックがあります。

デモ (jsfiddle)

var $poped = $('someselector');

// Trigger for the popover
$poped.each(function() {
    var $this = $(this);
    $this.on('hover',function() {
            var popover = $this.data('popover');
            var shown = popover && popover.tip().is(':visible');
            if(shown) return;        // Avoids flashing
            $this.popover('show');
    });
});

// Trigger for the hiding
 $('html').on('click.popover.data-api',function() {
    $poped.popover('hide');
});
于 2012-07-28T18:08:27.017 に答える
11

その方法を示すために jsfiddle を作成しました。

http://jsfiddle.net/3yHTH/

ボタンをクリックするとポップオーバーが表示され、ボタンの外側をクリックするとポップオーバーが非表示になります。

HTML

<a id="button" href="#" class="btn btn-danger">Click for popover</a>

JS

$('#button').popover({
    trigger: 'manual',
    position: 'bottom',
    title: 'Example',
    content: 'Popover example for SO'
}).click(function(evt) {
    evt.stopPropagation();
    $(this).popover('show');
});

$('html').click(function() {
    $('#button').popover('hide');
});
于 2012-07-28T17:40:33.397 に答える
5

http://getbootstrap.com/javascript/#popoversによると、

<button type="button" class="popover-dismiss" data-toggle="popover" title="Dismissible popover" data-content="Popover Content">Dismissible popover</button>

focus トリガーを使用して、ユーザーが次にクリックしたときにポップオーバーを閉じます。

$('.popover-dismiss').popover({
    trigger: 'focus'
})
于 2014-07-22T13:25:29.490 に答える
3

受け入れられた解決策を変更しました。私が経験したことは、一部のポップオーバーが非表示になった後、再度表示するには 2 回クリックする必要があるということでした。すでに非表示になっているポップオーバーで popover('hide') が呼び出されないようにするために私がしたことは次のとおりです。

$('body').on('click', function (e) {
    $('[data-original-title]').each(function () {
        //the 'is' for buttons that trigger popups
        //the 'has' for icons within a button that triggers a popup
        if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
            var popoverElement = $(this).data('bs.popover').tip();
            var popoverWasVisible = popoverElement.is(':visible');

            if (popoverWasVisible) {
                $(this).popover('hide');
                $(this).click(); // double clicking required to reshow the popover if it was open, so perform one click now
            }
        }
    });
});
于 2016-06-03T16:55:42.480 に答える
3

これはパーティーに遅れています...しかし、私はそれを共有したいと思いました. 私はポップオーバーが大好きですが、組み込み機能がほとんどありません。ポップオーバーにしたいすべてのブートストラップ拡張機能 .bubble() を作成しました。解雇の方法は4つ。外側をクリックし、リンクを切り替えて、X をクリックし、エスケープを押します。

自動的に配置されるため、ページからはみ出すことはありません。

https://github.com/Itumac/bootstrap-bubble

これは不当な自己宣伝ではありません...私は人生で何度も他の人のコードを手に入れてきたので、自分の努力を提供したいと思いました。それを回転させて、それがあなたのために働くかどうか見てください.

于 2013-10-14T14:47:29.777 に答える
3

これは以前ここで尋ねられました。私が与えた同じ答えはまだ適用されます:

同様のニーズがあり、Lee Carmichael による Twitter Bootstrap Popover のこの素晴らしい小さな拡張機能を見つけました。これは BootstrapX - clickover と呼ばれます。彼はまた、ここにいくつかの使用例を持っています. 基本的には、ポップオーバーをインタラクティブなコンポーネントに変更します。このコンポーネントは、ページの他の場所をクリックするか、ポップオーバー内の閉じるボタンをクリックすると閉じます。これにより、複数のポップオーバーを一度に開いたり、その他の優れた機能を多数使用したりできます。

于 2012-11-28T11:22:57.640 に答える
3

この解決策はうまくいきます:

$("body")   .on('click'     ,'[data-toggle="popover"]', function(e) { 
    e.stopPropagation();
});

$("body")   .on('click'     ,'.popover' , function(e) { 
     e.stopPropagation();
});

$("body")   .on('click'  , function(e) {
        $('[data-toggle="popover"]').popover('hide');
});
于 2019-05-11T20:46:24.447 に答える
2
jQuery("#menu").click(function(){ return false; });
jQuery(document).one("click", function() { jQuery("#menu").fadeOut(); });
于 2012-12-20T02:34:42.217 に答える
2

@mattdlockyer からの解決策に問題があることがわかりました (解決策をありがとう!)。このようなポップオーバー コンストラクターのセレクター プロパティを使用すると...

$(document.body').popover({selector: '[data-toggle=popover]'});

...BS3 の提案されたソリューションは機能しません。代わりに、2 つ目のポップオーバー インスタンスをローカルに作成します$(this)。これを防ぐための解決策は次のとおりです。

$(document.body).on('click', function (e) {
    $('[data-toggle="popover"]').each(function () {
        //the 'is' for buttons that trigger popups
        //the 'has' for icons within a button that triggers a popup
        if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
            var bsPopover = $(this).data('bs.popover'); // Here's where the magic happens
            if (bsPopover) bsPopover.hide();
        }
    });
});

前述のよう$(this).popover('hide');に、委任されたリスナーのために 2 番目のインスタンスが作成されます。提供されるソリューションは、既にインスタンス化されているポップオーバーのみを非表示にします。

皆さんの時間を少しでも節約できれば幸いです。

于 2015-03-02T17:48:47.053 に答える
2

セレクター委譲でポップオーバーを作成すると、「非表示」メソッドが機能しないようです。代わりに「破棄」を使用する必要があります。

私はそれを次のように機能させました:

$('body').popover({
    selector: '[data-toggle="popover"]'
});

$('body').on('click', function (e) {
    $('[data-toggle="popover"]').each(function () {
        //the 'is' for buttons that trigger popups
        //the 'has' for icons within a button that triggers a popup
        if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
            $(this).popover('destroy');
        }
    });
});

ここでJSfiddle

于 2014-10-31T13:10:29.347 に答える
2

以前の回答の多くを試しましたが、実際には何も機能しませんでしたが、このソリューションは機能しました:

https://getbootstrap.com/docs/3.3/javascript/#dismiss-on-next-click

ボタンではなくアンカータグを使用し、role="button" + data-trigger="focus" + tabindex="0" 属性に注意することをお勧めします。

元:

<a tabindex="0" class="btn btn-lg btn-danger" role="button" data-toggle="popover" 
data-trigger="focus" title="Dismissible popover" data-content="amazing content">
Dismissible popover</a>
于 2018-02-20T08:31:43.080 に答える
2

イベント バブリングを使用して、ポップアップを DOM から削除することもできます。少し汚れていますが、動作は問題ありません。

$('body').on('click touchstart', '.popover-close', function(e) {
  return $(this).parents('.popover').remove();
});

HTML で、ポップオーバーを閉じる必要があるポップオーバー内のコンテンツに .popover-close クラスを追加します。

于 2013-01-07T21:04:05.493 に答える
1

新しいポップオーバーが表示される前に、他のアクティブなポップオーバーを削除するだけです (ブートストラップ 3):

$(".my-popover").popover();

$(".my-popover").on('show.bs.popover',function () {
    $('.popover.in').remove();
});              
于 2014-01-17T14:48:45.427 に答える
1

私はこれを思いつきました:私のシナリオには同じページにもっと多くのポップオーバーが含まれており、それらを非表示にするだけで非表示になり、そのため、ポップオーバーの背後にあるアイテムをクリックすることはできませんでした. アイデアは、特定のポップオーバー リンクを「アクティブ」としてマークし、アクティブなポップオーバーを単に「トグル」できるようにすることです。そうすることで、ポップオーバーが完全に閉じます $('.popover-link').popover({ html : true, container: 'body' })

$('.popover-link').popover().on 'shown.bs.popover', ->
  $(this).addClass('toggled')

$('.popover-link').popover().on 'hidden.bs.popover', ->
  $(this).removeClass('toggled')

$("body").on "click", (e) ->
  $openedPopoverLink = $(".popover-link.toggled")
  if $openedPopoverLink.has(e.target).length == 0
    $openedPopoverLink.popover "toggle"
    $openedPopoverLink.removeClass "toggled"
于 2013-10-29T20:25:05.390 に答える
1

ポップオーバーに日付ピッカーやタイムピッカーのようなものがない限り、@guya からの回答は機能します。それを修正するために、これが私がやったことです。

if (typeof $(e.target).data('original-title') === 'undefined' && 
    !$(e.target).parents().is('.popover.in')) {
        var x = $(this).parents().context;
        if(!$(x).hasClass("datepicker") && !$(x).hasClass("ui-timepicker-wrapper")){
            $('[data-original-title]').popover('hide');
        }
}
于 2015-03-04T14:40:54.897 に答える
1

3.3.6でテストされ、2回目のクリックは問題ありません

        $('[data-toggle="popover"]').popover()
            .click(function () {
            $(this).popover('toggle');
        });;

        $(document).on('click', function (e) {
            $('[data-toggle="popover"]').each(function () {
                //the 'is' for buttons that trigger popups
                //the 'has' for icons within a button that triggers a popup
                if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
                    $(this).popover('hide');
                }
            });
        });
于 2016-07-25T17:04:42.190 に答える
0

デモ: http://jsfiddle.net/nessajtr/yxpM5/1/

var clickOver = clickOver || {};
clickOver.uniqueId = $.now();

clickOver.ClickOver = function (selector, options) {
    var self = this;

    //default values
    var isVisible, clickedAway = false;

    var callbackMethod = options.content;
var uniqueDiv = document.createElement("div");
var divId = uniqueDiv.id = ++clickOver.uniqueId;
uniqueDiv.innerHTML = options.loadingContent();

options.trigger = 'manual';
options.animation = false;
options.content = uniqueDiv;

self.onClose = function () {
    $("#" + divId).html(options.loadingContent());
    $(selector).popover('hide')
    isVisible = clickedAway = false;
};
self.onCallback = function (result) {
    $("#" + divId).html(result);
};

$(selector).popover(options);

//events
$(selector).bind("click", function (e) {
    $(selector).filter(function (f) {
        return $(selector)[f] != e.target;
    }).popover('hide');

    $(selector).popover("show");
    callbackMethod(self.onCallback);

    isVisible = !(clickedAway = false);
});

$(document).bind("click", function (e) {
    if (isVisible && clickedAway && $(e.target).parents(".popover").length == 0) {
        self.onClose();
        isVisible = clickedAway = false;
    } else clickedAway = true;
});

}

これが私の解決策です。

于 2013-03-04T08:20:09.220 に答える
0
$(document).on('click', function(e) {
  $('[data-toggle="popover"]').each(function() {
    if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
      $(this).popover('hide').data('bs.popover').inState.click = false
    }

  });
});
于 2017-01-06T05:34:53.217 に答える
0

このアプローチにより、ページ上の任意の場所をクリックしてポップオーバーを閉じることができます。別のクリック可能なエンティティをクリックすると、他のすべてのポップオーバーが非表示になります。animation:false が必要です。そうしないと、コンソールで jquery .remove エラーが発生します。

$('.clickable').popover({
 trigger: 'manual',
 animation: false
 }).click (evt) ->
  $('.clickable').popover('hide')
  evt.stopPropagation()
  $(this).popover('show')

$('html').on 'click', (evt) ->
  $('.clickable').popover('hide')
于 2013-08-05T08:40:21.567 に答える
0
$('html').on('click.popover', function (e) {
    var allpopins = $('.popover.in');
    if (allpopins.has(e.target).length > 0 &&
        !$('.btn', allpopins).is(e.target))
        return;
    // recognise pop-up 
    var id = $(e.target).attr('aria-describedby');
    var popin = $("#" + id);
    //on any button click in entire pop-up hide this pop-ups
    $(popin).on(".btn", function () { popin.remove(); });
    // on any place out of entire popup hide all pop-ups 
    $('.popover.in').not(popin).remove();
});

これが私の最高のパフォーマンス ソリューションです。乾杯。

于 2015-05-15T06:33:32.177 に答える
0

OK、これはスタックオーバーフローで実際に何かに答える最初の試みなので、ここでは何もしません:P

この機能が実際に最新のブートストラップで箱から出してすぐに動作するかどうかは、あまり明確ではないようです (ユーザーがクリックできる場所を妥協するつもりがある場合。ホバー自体は機能しますが、iPad ではクリックがトグルとして機能します。

最終的には、デスクトップ上でホバーまたはクリックできるようになります (ほとんどのユーザーはホバーします)。タッチ デバイスでは、要素に触れるとその要素が表示され、もう一度触れると削除されます。もちろん、これは元の要件からのわずかな妥協ですが、少なくともコードはよりクリーンになりました:)

$(".my-popover").popover({ トリガー: 'ホバーをクリック' });

于 2013-08-16T04:03:31.220 に答える
0

私のようにAngularを使用している場合に備えて、Angularディレクティブを追加するだけで、答えは非常にうまく機能します。

app.directive('popover', ['$document', function($document) {
    return {
        restrict: 'EA',
        link: function(scope, elem, attrs) {
            $(document).ready(function() {
                $('[data-toggle="popover"]').popover();
            });

            elem.bind('click', function(e) {
                $('#notification').popover('toggle');
            })

            $('body').on('click', function (e) {
                //the 'is' for buttons that trigger popups
                //the 'has' for icons within a button that triggers a popup
                if (!elem.is(e.target)
                    && elem.has(e.target).length === 0
                    && $('.popover').has(e.target).length === 0) {
                    elem.popover('hide');
                }
            });
        }
    };
}]);

HTML コード:

<a popover tabindex="0" role="button"
   id="notification"
   data-toggle="popover" data-trigger="manual"
   data-container="body" data-placement="bottom"
   data-content="This is a popover">
   Popover button
</a>

data-trigger='click focus'ブートストラップによると、use と同じくらい簡単なはずです。

ポップオーバーのトリガー方法 - クリック | ホバー | フォーカス | マニュアル。複数のトリガーを渡すことができます。スペースで区切ります。手動は他のトリガーと組み合わせることはできません。

ただし、クリックとフォーカスを一緒に使用しても、理由は不明ですが、手動で切り替える必要があります。

于 2016-06-21T14:42:35.233 に答える
0

次のようなコードを使用してポップオーバー リンクを動的に設定していたため、mattdlockyer のソリューションに問題がありました。

$('body').popover({
        selector : '[rel="popover"]'
});

だから私はそれをそのように修正しなければなりませんでした。それは私にとって多くの問題を修正しました:

$('html').on('click', function (e) {
  $('[data-toggle="popover"]').each(function () {
    //the 'is' for buttons that trigger popups
    //the 'has' for icons within a button that triggers a popup
    if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
        $(this).popover('destroy');
    }
  });
});

destroy は要素を取り除くので、ポップオーバーの初期化ではセレクター部分が重要になることに注意してください。

于 2014-09-08T21:19:51.610 に答える
-2

data-trigger="focus click" を設定するだけです

于 2020-10-06T10:56:13.967 に答える