普段は何かしらのライブラリを探して使ってますが、お勉強がてらJavaScriptだけで作ってみることに。
実装する機能
- セレクトボックスをクリックすると選択肢が表示
- 選択肢をクリックするとセレクトボックスに移動
- セレクトボックスの選択肢を×ボタンで削除可能
- セレクトボックス内 or 要素外をクリックすることで選択肢を閉じる
完成品
See the Pen Untitled by Takeshi Hashimoto (@tks-hsmt) on CodePen.
実装時のポイント① クリックイベント時の要素判定
イベントを設定した要素(addEventListenerの対象要素)を取得したい場合は「Event.currentTarget」を利用します。
イベントが発生した要素(クリックされた要素)を取得したい場合は「Event.target」を利用します。
今回だと要素外のエリアをクリックされたかを調べる際にはEvent.targetを利用しています。
逆に、表示エリアや選択エリアをクリックされた場合は要素のclassを取得したい為、Event.currentTargetを利用しています。
document.addEventListener('click', (e) => {
if (e?.target?.closest('.multiple-select')) return;
this.close();
});
const displays = document.querySelectorAll('.display-area') || [];
[...displays].forEach((display) => display.addEventListener('click', (e) => {
this.toggle(e.currentTarget);
}));
Event.target
Event.currentTarget
実装時のポイント② 親要素の取得
今回クリックされた要素の親を遡って、その配下のエリアを取得して表示を変える仕組みにしています。
要素の親を検索する為、Element.closest()を利用しています。
※IEは対応していません。
const select = element.closest('.multiple-select').querySelector('.select-area');
if (select.childElementCount === 0) return;
if (!select.classList.contains('is-open')) {
this.selectAreaPositioning(element);
}
select.classList.toggle('is-open');
実装時のポイント③ クリックイベントの伝播の抑止
セレクトボックスはクリックイベントを監視し、選択肢の表示/非表示を行います。
また、セレクトボックス内の選択肢の×ボタンをクリックした際にはその要素を選択肢に戻します。
この時何も意識しないと、選択肢の×ボタンをクリックした際に、親要素のセレクトボックスにイベントが伝播してしまい、
選択肢が閉じたり開いたりしてしまいます。
そうならないように、×ボタンクリック時にはEvent.stopPropagation()を利用しています。
const buttons = document.querySelectorAll('.delete-button') || [];
[...buttons].forEach((button) => button.addEventListener('click', (e) => {
e.stopPropagation();
this.switching(e.currentTarget);
}));