2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JavaScriptだけでMultiple Select

Last updated at Posted at 2021-12-12

普段は何かしらのライブラリを探して使ってますが、お勉強がてらJavaScriptだけで作ってみることに。

実装する機能

  • セレクトボックスをクリックすると選択肢が表示
  • 選択肢をクリックするとセレクトボックスに移動
  • セレクトボックスの選択肢を×ボタンで削除可能
  • セレクトボックス内 or 要素外をクリックすることで選択肢を閉じる

完成品

See the Pen Untitled by Takeshi Hashimoto (@tks-hsmt) on CodePen.

実装時のポイント① クリックイベント時の要素判定

イベントを設定した要素(addEventListenerの対象要素)を取得したい場合は「Event.currentTarget」を利用します。
イベントが発生した要素(クリックされた要素)を取得したい場合は「Event.target」を利用します。
今回だと要素外のエリアをクリックされたかを調べる際にはEvent.targetを利用しています。
逆に、表示エリアや選択エリアをクリックされた場合は要素のclassを取得したい為、Event.currentTargetを利用しています。

handleOuterAreaClick
    document.addEventListener('click', (e) => {
      if (e?.target?.closest('.multiple-select')) return;
      this.close();
    });
handleDisplayAreaClick
    const displays = document.querySelectorAll('.display-area') || [];
    [...displays].forEach((display) => display.addEventListener('click', (e) => {
      this.toggle(e.currentTarget);
    }));

Event.target
Event.currentTarget

実装時のポイント② 親要素の取得

今回クリックされた要素の親を遡って、その配下のエリアを取得して表示を変える仕組みにしています。
要素の親を検索する為、Element.closest()を利用しています。
※IEは対応していません。

toggle
    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');

Element.closest()

実装時のポイント③ クリックイベントの伝播の抑止

セレクトボックスはクリックイベントを監視し、選択肢の表示/非表示を行います。
また、セレクトボックス内の選択肢の×ボタンをクリックした際にはその要素を選択肢に戻します。
この時何も意識しないと、選択肢の×ボタンをクリックした際に、親要素のセレクトボックスにイベントが伝播してしまい、
選択肢が閉じたり開いたりしてしまいます。
そうならないように、×ボタンクリック時にはEvent.stopPropagation()を利用しています。

handleDeleteButtonClick
    const buttons = document.querySelectorAll('.delete-button') || [];
    [...buttons].forEach((button) => button.addEventListener('click', (e) => {
      e.stopPropagation();
      this.switching(e.currentTarget);
    }));

Event.stopPropagation()

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?