[解決済み] ドロップダウンを外部クリックで閉じるには?
2022-04-24 19:07:37
質問内容
ログインメニューのドロップダウンを、ユーザーがそのドロップダウンの外をクリックしたときに閉じたいのですが、Angular2とAngular2の"aproach"でそれをしたいのですが・・・。
解決策を実装したのですが、本当に自信がありません。同じ結果を得るための最も簡単な方法があるはずなので、もし何かアイデアがあれば...話し合いましょう :) !
以下は私の実装です。
ドロップダウンのコンポーネントです。
これは、私のドロップダウンのコンポーネントです。
- このコンポーネントがvisibleに設定されるたびに(たとえば、ユーザーがボタンをクリックして表示するとき)、quot;global" rxjsのサブジェクトにサブスクライブされます。 ユーザーメニュー の中に格納されています。 サブジェクトサービス .
- そして、非表示になるたびに、この件名の配信を停止する。
- どこをクリックしても 内 このコンポーネントのテンプレートは onClick() メソッドで、トップ(およびアプリケーションコンポーネント)へのイベントのバブリングを停止します。
以下はそのコードです。
export class UserMenuComponent {
_isVisible: boolean = false;
_subscriptions: Subscription<any> = null;
constructor(public subjects: SubjectsService) {
}
onClick(event) {
event.stopPropagation();
}
set isVisible(v) {
if( v ){
setTimeout( () => {
this._subscriptions = this.subjects.userMenu.subscribe((e) => {
this.isVisible = false;
})
}, 0);
} else {
this._subscriptions.unsubscribe();
}
this._isVisible = v;
}
get isVisible() {
return this._isVisible;
}
}
アプリケーションの構成要素です。
一方、アプリケーション・コンポーネント(ドロップダウン・コンポーネントの親)があります。
- このコンポーネントは、すべてのクリックイベントをキャッチし、同じrxjsのSubject( ユーザーメニュー )
以下はそのコードです。
export class AppComponent {
constructor( public subjects: SubjectsService) {
document.addEventListener('click', () => this.onClick());
}
onClick( ) {
this.subjects.userMenu.next({});
}
}
気になること
- これらのコンポーネント間のコネクターとして機能するグローバルなSubjectを持つという考えには、本当に納得がいきません。
-
その
セットタイムアウト
: これは、ユーザーがドロップダウンを表示するボタンをクリックした場合に、そうでなければ何が起こるかを示すために必要です。
- ユーザはドロップダウンを表示するためにボタン(ドロップダウン・コンポーネントの一部ではない)をクリックします。
- ドロップダウンが表示され は、すぐにuserMenuのサブジェクトに登録されます。 .
- クリックイベントはアプリコンポーネントにバブルアップされ、キャッチされます。
- アプリケーションコンポーネントは ユーザーメニュー 件名
- ドロップダウン・コンポーネントは、このアクションを ユーザーメニュー で、ドロップダウンを非表示にします。
- 最後にはドロップダウンは表示されません。
このセットのタイムアウトは、問題を解決する現在のJavaScriptコードのターンの終わりにサブスクリプションを遅らせますが、私の意見では非常にエレガントな方法で。
もし、もっと簡単な、もっと良い、もっと賢い、もっと速い、もっと強力な解決策をご存知でしたら、ぜひ教えてください :) !
解決方法は?
を使用することができます。
(document:click)
イベントを使用します。
@Component({
host: {
'(document:click)': 'onClick($event)',
},
})
class SomeComponent() {
constructor(private _eref: ElementRef) { }
onClick(event) {
if (!this._eref.nativeElement.contains(event.target)) // or some similar check
doSomething();
}
}
もう一つの方法は、カスタムイベントをディレクティブとして作成することです。Ben Nadelによるこれらの投稿をチェックしてみてください。
関連
-
[解決済み】JavaScript TypeError: null のプロパティ 'style' を読み取ることができない
-
[解決済み】ERROR エラーです。スイッチのname属性が指定されていないフォームコントロールの値アクセッサがない
-
[解決済み] 要素外でのクリックを検出するにはどうすればよいですか?
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] jQueryで要素が非表示になっているかどうかを確認するには?
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] JavaScriptで文字列をbooleanに変換するにはどうしたらいいですか?
-
[解決済み] Twitter Bootstrapのメニューをクリックではなく、ホバーでドロップダウンさせる方法
-
[解決済み】別のウェブページにリダイレクトするにはどうすればいいですか?
-
[解決済み】オブジェクトからプロパティを削除する(JavaScript)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
vue3レスポンシブ対応のためのsetup+ref+reactive
-
Vueがechartsのtooltipにクリックイベントを追加するケーススタディ
-
元のイベントが実行されなかった後に要素を追加するためのjQueryソリューション
-
Vueのクラススタイルの使い方の詳細
-
[解決済み】Node Version Manager のインストール - nvm コマンドが見つかりません。
-
[解決済み】リソースの読み込みに失敗した:Bind関数でサーバーが500(Internal Server Error)のステータスで応答した【非公開
-
[解決済み】gulp anythingを実行するたびに、アサーションエラーが発生します。- タスク関数を指定する必要があります
-
[解決済み】ERROR エラーです。スイッチのname属性が指定されていないフォームコントロールの値アクセッサがない
-
[解決済み】ExpressJS - throw er Unhandled errorイベント
-
[解決済み】React-Redux: アクションはプレーンオブジェクトでなければならない。非同期アクションにはカスタムミドルウェアを使用する