ポップオーバーの外側をクリックすると、Angular-bootstrap popover
sを閉じようとしています。この質問への回答によると、これは新しいpopover-is-open
属性: 非表示Angular UI Bootstrap外側をクリックするとポップオーバー
現在、私のHTMLは次のようになっています。
<div
ng-click="level.openTogglePopover()"
popover-template="level.changeLevelTemplate"
popover-trigger="none"
popover-placement="right"
popover-is-open="level.togglePopover">
<button class="btn btn-default btn-xs" type="button">
<span class="glyphicon glyphicon-sort"></span>
</button>
</div>
...そして私の関連するコントローラーコード:
vm.togglePopover = false;
vm.openTogglePopover = function() {
vm.togglePopover = !vm.togglePopover;
};
これは、上記のボタンをクリックしたときにポップオーバーを開いたり閉じたりするのに最適です。私の質問は、ポップオーバーの外側のどこかをクリックしたときにポップオーバーを閉じるようにこの機能を拡張するにはどうすればよいですか?これを実現するためにイベント処理をどのようにセットアップしますか?
まず、ポップオーバーをanyクリックで閉じたい場合は、ポップオーバーの外側だけでなく、既存のUI-Bootstrapコードを使用してそれを行うことができます。
<button class="btn btn-default btn-xs" type="button"
popover-template="level.changeLevelTemplate"
popover-trigger="focus"
popover-placement="right">
<span class="glyphicon glyphicon-sort"></span>
</button>
ここでの秘訣は、周囲の<div>
をドロップし、popover-trigger="focus"
をボタンの右に配置することです。
ポップオーバーコンテンツの外側のクリックに対してのみ実際にポップオーバーを閉じる必要がある場合は、さらに困難になります。次のような新しいディレクティブが必要です。
app.directive('clickOutside', function ($parse, $timeout) {
return {
link: function (scope, element, attrs) {
function handler(event) {
if(!$(event.target).closest(element).length) {
scope.$apply(function () {
$parse(attrs.clickOutside)(scope);
});
}
}
$timeout(function () {
// Timeout is to prevent the click handler from immediately
// firing upon opening the popover.
$(document).on("click", handler);
});
scope.$on("$destroy", function () {
$(document).off("click", handler);
});
}
}
});
次に、ポップオーバーテンプレートで、最も外側の要素のディレクティブを使用します。
<div click-outside="level.closePopover()">
... (actual popover content goes here)
</div>
最後に、コントローラーにclosePopover
関数を実装します。
vm.closePopover = function () {
vm.togglePopover = false;
};
ここで行ったことは次のとおりです。
close-popover
ディレクティブを追加した要素の外にある場合:close-popover
の値であるコードを呼び出しますポップオーバーテンプレート内からコントローラーメソッドを呼び出す必要があるため、これは最もクリーンなソリューションではありませんが、私が思いついた最高のソリューションです。
Angular-ui 1.0.0以降、ツールチップとポップオーバー用の新しいoutsideClick
トリガーがあります( this pull request で導入):
<div
uib-popover-template="level.changeLevelTemplate"
popover-trigger="outsideClick"
popover-placement="right">
<button class="btn btn-default btn-xs" type="button">
<span class="glyphicon glyphicon-sort"></span>
</button>
</div>
私が正しく理解していれば、ユーザーがポップオーバー自体の内側以外のほとんどの場所をクリックしたときに、実際の閉じるボタンを除いて、ポップオーバーを閉じる必要があります。これは、イベントリスナーで実現できます。
$('html').click(function() {
if(!$(event.target).is('#foo')) {
// Code to hide/remove popovers
}
});
これをチェックしてください plunkr 。
または、特定のシナリオでは:
$('html').click(function() {
if(!$(event.target).is('.my-popover-class')) {
vm.togglePopover = false;
}
})
ポップオーバーの外側をクリックすると、ポップオーバーが閉じます
少し前に私はこの答えが役に立ったと感じました: Twitterを閉じる方法Bootstrap外をクリックしてポップオーバー?
私のデモの1つで使用したコード(angular
とjQuery
eventの処理の混合は推奨されません)は特定です私のニーズに合わせて、いくつかのアイデアを与えるかもしれません:
app.directive("eventlistener", function($rootScope) {
$(window).resize($rootScope.closeAllPopovers); // because Bootstrap popovers don't look good when misplaced
return {
link: function(scope, element, attrs) {
$('body').on('mouseup touchend', $rootScope.closeAllPopovers);
}
};
});
$rootScope.closeAllPopovers = function (e) {
$('[data-toggle="popover"]').each(function () {
if (e) {
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$(this).popover('hide');
}
} else {
// No event passed - closing all popovers programmatically
$(this).popover('hide');
}
});
};
また、以下の違いを確認することをお勧めします。
新しい*-is-open
属性を使用する場合、イベント処理は行われないため、イベント処理を自分で行う必要があります。
ポップオーバーの開閉をプログラムで制御する必要がない場合は、組み込みのfocus
トリガーを使用して必要なものを提供できます。