[Vue.js, JavaScript]クリックされた要素を特定してdata属性から情報を取得する方法

クリックされた要素を特定してdata属性から情報を取得する方法

クリックされた要素を特定して、そこからdata属性の値を取得、Vue.jsのdataに渡して表示してみる

脱jQueryがささやかれて久しい昨今。
だんだんと、jQueryが使えない、使わせてもらえない制作現場も増えてきたように感じています。

そこで今回は、素のjavascript(俗にいう Vanilla JS というやつです)を使って、
ページのクリック位置を特定する方法について書いていきます。

クリックされた要素からdata属性を取得して、
それをVue.jsのdataに渡して、表示するところまで書いてみたいと思います。

document.addEventListener をつかう

  <v-chip data-position="leftButton" color="indigo" dark>
    <v-icon>mdi-emoticon-excited-outline</v-icon>
    Like it !
  </v-chip>

↑こんな形で、ページ内にクリックできる要素があったとします。
例として、Vuetify の v-chip を使用しています。( v-chip は、v-btn より小さめのクリック可能なコンポーネントです)
v-chipには、data属性として data-position という属性を定義してあります。
クリックした際に、これを取得するには、次のように記述します。
以下のコードは、Vue.js の mounted() 内に記述することを想定しています。

const me = this;
document.addEventListener('click', function(e) {
  if (e.target.classList.contains('v-chip__content')) {
    me.myclicked = e.target.parentNode.dataset.position;
  }
});

かつて、多くのWeb制作者たちがお世話になったjQueryの場合だと、
ページ上のクリックイベントを取得する場合は
$(document).on(‘click’)…..(中略)
のように書いていたかと思います。

それを素のjavascriptに置き換えると、
上記のような書き方で動作します。
2行目の
document.addEventListener('click', …. (中略)
で、クリックイベントを文字通り、リッスンします。
これでページ全体のクリックイベントを検知することができるようになり、
e.target に、クリックイベントが発生した箇所の要素がもつ情報が
返ってくるので、それらの情報にアクセスが可能になります。

3行目で
if (e.target.classList.contains('v-chip__content'))
としているのは、何らかの条件を与えてあげないと、
ページのどこをクリックしてもこの記述が動いてしまうので、それを制御するためです。

v-chip というコンポーネントは、ページ上に展開されると次のように
span > span > i
と、spanが入れ子になる構造になっています。
上記の条件分岐は、
「子階層の span要素が v-chip__content という class を持っていた場合」を判定しているということです。

<span class="v-chip theme--dark v-size--default indigo" data-position="leftButton">
  <span class="v-chip__content">
    <i aria-hidden="true" class="v-icon notranslate mdi mdi-emoticon-excited-outline theme--dark"></i>
    Like it !
  </span>
</span>

また、v-chip が上記のような構造になっているため、
クリックされた箇所がもつdata属性にアクセスするためには、

4行目にある通り
e.target.parentNode.dataset.position;
として、parentNode を加えることが必要になります。
(実際にクリックイベントが起きる位置は、内側の v-chip__content を持っている階層のspanのため。)
parentNode というのは、すごくざっくり言うと、
文字通り親ノードにアクセスできる記述です。
こちらで詳しく解説されています → Node.parentNode – Web API | MDN

上記の記述で
クリックされた要素のdata属性を取得することができるため、
それを、Vue.js 側であらかじめ定義しておいた
myclicked という data に格納している、
そんな流れになっています。(もちろん、Vue.jsを使っていなかったら、普通に変数に格納でも大丈夫ですし、別のフレームワークを使用している場合は、適宜置き換えて読んでください)

なお、1行目で
const me = this;
と、 this をあえて変数に代入しているのは、javascript における this というものの
スコープの概念を柔軟に使用するために行なっています。このスコープの概念については、
おそらく制作の際に何度も何度も javascript と向き合っていれば、
おのずと理解できる部分かと思いますので、今回これについて詳しく書くのは省略します。

クリックされた要素を特定 → そこからdata属性の値を取得 → Vue.jsのdataに渡して表示してみたサンプル

上記のような仕組みで
クリックされた要素を特定 → data属性の値を取得 → Vue.jsのdataに渡して表示してみた
サンプルを、実際に動く状態のものを作成してあります。
次のリンクより、確認する事ができます。
クリックされたボタンからdata属性の値を取得するサンプル

この記事のまとめ

このところ、ひたすら Vuetify のUIコンポーネントを紹介する記事を書いてきましたが、
今回は、すこしだけ踏み込んで
素の javascript を使い、
クリックイベントを取得してそれを Vue.js の data に渡して、表示してみる
という事について書いてみました。

今回のサンプル作成の際も、
綺麗なUIパーツが手軽にさくっと作成できるという観点で、
やはり Vuetify が活躍してくれました。とても感謝しています。

いずれ、今回使用した v-chip というUIコンポーネントに関する記事も、書けたらと思っています。

※この記事は、内容の品質向上を目的に、随時更新を行う場合があります。