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

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

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

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

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

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

Vue.jsの場合、とてもシンプルな方法で取得が可能です

素のjavascriptを使った方法の前に、
Vue.jsを使用している場合に使える、簡単な方法から書いておきたいと思います。

クリックされた要素を特定して、その要素が持つ情報を得たい場合。
Vue.jsを使用している場合は、とてもシンプルにクリックイベントを取得する方法があります。

それは、Vue.jsの $event 変数 を使用する方法です。
どういうことかと言うと、次のように使います。

<button @click="myFunction($event)" data-sample="clicked">
  クリックイベントを取得したいボタン
</button>

↑こういうボタン要素があったとして、@click(v-on:clickの省略形)に関数を指定。
ボタンを押した時に実行する関数を定義して、その引数に $event を渡しておきます。

それを、実行される関数側で次のように受け取ってあげれば、
クリックされた要素が持つ各情報にアクセスすることが可能です。

myFunction(event) {
  console.log(event);
  // ↑ クリックイベント全体を取得したい場合
  
  console.log(event.target.dataset.sample);
  // ↑ target.dataset.data名 で対象のdata属性の値が取得できる
}

↑上記のように、Vue.jsの場合は $event を使用することで
とてもシンプルに取得することができます。

このようにクリックした要素から取得したdata属性を受け取って、
それをVue.jsのdataに渡してあげ、
{{}}(マスタッシュ構文)などで展開してあげれば、
表示することが可能と言うわけですね。

この記事の続編記事では、「取得したdata属性の値をどう使うか?」について、異なる要素内にあるリストの見た目を更新する簡単な例をもとに書いています。
ぜひそちらもご覧ください。

対象の記事ボタンをクリックしたら、別の要素内にあるリストのstyleが変わるUIを作る方法[JavaScript]

上記以外の方法。地道に document.addEventListener をつかう

こちらの例は地道に、document.addEventListener をつかう方法です。

Vue.js以外でも使用可能な方法ですが、こちらは地道な方法で回りくどいかもしれません。

  <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属性の値を取得するサンプル

この記事の続編記事では、「取得したdata属性の値をどう使うか?」について、異なる要素内にあるリストの見た目を更新する簡単な例をもとに書いています。
ぜひそちらもご覧ください。

対象の記事ボタンをクリックしたら、別の要素内にあるリストのstyleが変わるUIを作る方法[JavaScript]

この記事のまとめ

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

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

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

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

この記事の続編記事では、「取得したdata属性の値をどう使うか?」について、異なる要素内にあるリストの見た目を更新する簡単な例をもとに書いています。
ぜひそちらもご覧ください。

対象の記事ボタンをクリックしたら、別の要素内にあるリストのstyleが変わるUIを作る方法[JavaScript]

この記事をシェアする: