Help us understand the problem. What is going on with this article?

Google タグマネージャーで子孫要素のクリックイベントもきっちり検出する

Google タグ マネージャー (以下 GTM と表記)にはクリックイベントを検出するためのトリガータイプとして「すべての要素」と「リンクのみ」の二種類が用意されています。「すべての要素」を利用するとリンクだけでなくボタンやフォームなどの要素もターゲットに指定することができますが、ターゲットの子孫要素のイベントは検出してくれません。

この仕様は Google Analytics (以下 GA と表記)などの外部サービスにクリックのイベントデータを送出するといったユースケースで問題となる可能性があります。例えば以下のような HTML において <button> をイベントターゲットに指定した場合、子要素の <i> がクリックされてもトリガーはそのイベントを検出しません。

<button>  <!-- button 要素のクリックは検出される -->
  <i class="material-icons">close</i>  <!-- icon 要素のクリックは検出されない! -->
</button>

この記事では、子孫要素のクリックイベントも含めてターゲットのイベントとして扱う方法について考えてみます。

TL;DR

  • トリガーの発生条件に CSS セレクタでターゲット要素とその子孫要素の両方を指定する。
  • カスタム JavaScript の変数として、クリックされた要素に最も近いターゲット要素(の属性値など)を返す関数を作成する。

シチュエーション

GTM を経由して、クリックイベントをトリガーに GA へイベントデータを送出するシチュエーションについて考えます。例えば以下のような HTML について考えます。

<body>
  <a href="https://example.com/products/999"
     target="_blank"
     data-tracking-category="product-list"
     data-tracking-action="click-product"
     data-tracking-label="thumbnail">
    <div class="thumbnail-wrapper">
      <p class="product-name"></p>
      <img class="thumbnail" src="thumbnail.jpg">
      <div class="logo-wrapper">
        <img class="logo" src="logo.jpg">
      </div>
    </div>
  </a>
</body>

ここで GTM のコンテナスニペットは省略しています。

ターゲット要素に data-tracking-category といった属性を仕込んでおき、この値によってどの要素がクリックされたか識別できるようにしています。 GA のイベント要素については公式のヘルプページを参照してください。

Google Tag Manager の設定

トリガー

まず data-tracking-category を属性に持つ要素、およびその子孫要素のクリックイベントを検出するトリガーを作成します。今回は Click - Data Tracking という名前にして、以下のように設定します。

  • トリガーのタイプ: 「クリック - すべての要素」
  • このトリガーの発生場所: 「一部のクリック」
  • イベント発生時にこれらすべての条件が true の場合にこのトリガーを配信します:
    • 「Click Element」
    • 「CSS セレクタに一致する」
    • [data-tracking-category], [data-tracking-category] *

[data-tracking-category] でターゲット要素を、 [data-tracking-category] * でその子孫要素をそれぞれ取得することができます。

変数

次にクリックされた箇所の data-tracking-category などの値を格納する変数を作成します。通常、トリガーによって検出されたイベントの発生した要素(ここではクリックされた要素)の情報は「自動イベント変数」を使って取得することができます。ただし今回の場合、子孫要素がクリックされた場合に親の data-tracking-category を取得する必要があり、「自動イベント変数」ではこれを実現できません。

この問題の解決方法について Simo Ahava さんのブログ記事を参考にさせてもらいました。まず utility 関数として Find Closest という変数を作成します。

Find Closest
function() {
  return function(target, selector) {
    while (!target.matches(selector) && !target.matches('body')) {
      target = target.parentElement;
    }
    return target.matches(selector) ? target : undefined;
  }
}

この変数では引数 selector に渡された CSS セレクタに一致する要素が見つかるまで target から再帰的に親要素を辿ります。この引数に [data-tracking-category] を指定することで、 data-tracking-category 属性を持つ親要素が取得できるという寸法です。

実際に data-tracking-category の値を取得する変数を Closest Data Tracking Category という名前で以下のように作成します。

Closest Data Tracking Category
function() {
  var el = {{Find Closest}}({{Click Element}}, '[data-tracking-category]');
  return typeof el !== 'undefined' ? el.getAttribute('data-tracking-category') : undefined;
}

{{Click Element}} は GTM の組み込み変数で、名前の通りクリックされた要素が格納されます。
これと同様に Closest Data Tracking ActionClosest Data Tracking Label も作成しておきます。

タグ

最後に GA に情報を送るためのタグを作成します。

  • タグの設定
    • タグの種類: 「Google アナリティクス: ユニバーサル アナリティクス」
    • トラッキング タイプ: 「イベント」
    • カテゴリ: {{Closest Data Tracking Category}}
    • アクション: {{Closest Data Tracking Action}}
    • ラベル: {{Closest Data Tracking Label}}
  • トリガー
    • Click - Data Tracking

その他 GA の設定などは環境に合わせて適宜行ってください。

動作確認

最後にプレビューモードで動作確認します。トラッキングしたい要素およびその子孫要素をクリックし、イベントが発火すること、変数に目的の値が設定されていることが確認できればオーケーです!

!

!

macloud
M&Aクラウドは「テクノロジーの力で、M&Aに流通革命を」をミッションにM&Aプラットフォーム「M&Aクラウド」を開発運営するスタートアップです。
https://macloud.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away