ドロップダウンなどを表示したときに、領域外をクリックしたら閉じたい。 HTMLだと、どのように実装するのが一般的なのかわからなかったのでAngularのUI Bootstrapを参考にしてみたよ。
Dropdown
documentにイベントハンドラを登録。
// https://github.com/angular-ui/bootstrap/blob/v1.1.0/src/dropdown/dropdown.js#L13 $document.on('click', closeDropdown); // ... var closeDropdown = function(evt) { // ... // dropdown内をクリックかつ'outsideClick'が設定されている場合は閉じない var dropdownElement = openScope.getDropdownElement(); if (evt && openScope.getAutoClose() === 'outsideClick' && dropdownElement && dropdownElement[0].contains(evt.target)) { return; } // ... openScope.isOpen = false; // ... };
補足: dropdownは複数開くことができないようになっている。uibDropdownServiceが管理している。
Modal
自身(全領域カバーしている)にイベントハンドラを登録。
// https://github.com/angular-ui/bootstrap/blob/v1.1.0/src/modal/modal.js#L165 element.on('click', scope.close);
documentに登録する方法だとこんな感じでしょうか。
class Controller { closeHandler: () => void; /*@ngInject*/ constructor( private $document: ng.IDocumentService, private $element: ng.IAugmentedJQuery, private $scope: ng.IScope ) { } $onInit() { this.closeHandler = () => { this.close(); this.$scope.$apply(); }; this.$element.on('click', ($event) => { // this.$document.on を無効にするため $event.stopPropagation(); }); } $onDestroy() { this.close(); } open() { // 何かの処理 // ... this.$document.on('click', this.closeHandler); } close() { // 何かの処理 // ... this.$document.off('click', this.closeHandler); } } const components: ng.IComponentOptions = { templateUrl: 'foo.html', controller: Controller, bindings: {} }; export default components;