Alpine.jsで特定の要素の外側がクリックされたことを検知する方法

こんにちは。エキサイトでデザイナーをしている齋藤です。

今回はAlpine.jsで、特定の要素の外側がクリックされたことを検知できる、x-onのModifierの一つである.outsideが便利だったのでシェアしたいと思います。

作りたいもの

冒頭に作りたいものをお示しします。CodePenをご用意しましたので、ぜひ触れてみてください。

ドロップダウンの場合、ボタンのみではなく、ドロップダウンの外側をクリックしても閉じられるようにすることで、ユーザーはより直感的に操作ができ、体験も向上すると考えます。

See the Pen Untitled by AyumuSaito (@ayumusaito-excite) on CodePen.

これを実現するためには、ユーザーが特定の要素の外側をクリックしたことを検知する必要がありますが、純粋なJSですと複数行の記述が必要となる一方で、Alpine.jsであれば1行で解決します。

まずはドロップダウンを作ってみる

まずは、Alpine.jsで簡単なドロップダウンの挙動を作ってみます。

<div x-data="{ isOpen: false }">
  <button @click="isOpen = !isOpen">
   ボタン
  </button>
  <div x-show="isOpen">
    コンテンツ
  </div>
</div>

これでボタンをクリックすると、isOpenの真偽値が入れ替わり、x-show属性のある要素の表示/非表示も切り替わるシンプルなドロップダウンの仕組みを作ることができました。

x-on.outsideで要素の外側がクリックされたことを検知する

先の例のままですと、ボタンのみでしか操作できません。

ボタンに加えて、x-show属性のある要素の外側がクリックされた場合にもisOpenfalseになるようにしたいです。

このような場合に、x-on:click.outsideを使用すると、要素の外側がクリックされたことを検知できます。

<div x-data="{ isOpen: false }">
  <button @click="isOpen = !isOpen">
   ボタン
  </button>
  <div x-show="isOpen" @click.outside="isOpen = false">
    コンテンツ
  </div>
</div>

x-show属性のある要素に@click.outside="isOpen = false"を追加します。

これで、x-show属性のある要素の外側がクリックされた場合に、isOpenfalseにすることができるようになりました。

なお、x-on:@で代替することができます。(例:x-on:clickの場合は@click

さいごに

Alpine.jsは少ない記述量で処理を実現できる上、HTMLタグの属性としてJSを記述するため、JSと対象となるHTML要素が散らばらずに一体となることから、開発体験も良いと感じています。

この記事が、これからAlpine.jsを使い始めるという方の一助となれば幸いです。

ご精読ありがとうございました。