Googleアナリティクスで特定の要素を表示したときにイベントトラッキングする

Googleアナリティクスなどでページの精読状況をトラッキングする際、「特定ピクセル以上スクロールする」「画面の○%以上スクロールする」ことがあるが、同様に「特定の要素を表示したとき」という条件でトラッキングしたいときもある。コンテンツの精読だけでなく、たとえばクーポンをページに仕込んでおいてその表示回数をカウントするなどのケースでも使える。

そのような場合にエレメントの座標を取得して、そこまでスクロールしたら発火するというアイデアがあるが、実はスマートフォンでは機種によって画面の幅が異なるため、テキスト部分の行数が変わり、縦座標の値も変わってくるという問題がある。単純に縦の位置を取得するだけでは使えないのである。

ここではユニバーサルアナリティクスの生タグでそれを回避する方法を説明する。なお現在はGoogleタグマネージャーを使えば簡単に実装できるためあまり役には立たないかもしれない。

element.getBoundingClientRect()というメソッド

element.getBoundingClientRect()というメソッドを使う。element.getBoundingClientRect()の戻り値はオブジェクトで、

var oRect = element.getBoundingClientRect();

oRectの中身は以下のようなものになる

{
  'bottom': 20,
  'height': 52,
  'left': 13,
  'right': 993,
  'top': -32,
  'width': 980
};

プロパティの意味は

  • widthheightはエレメントのサイズ(固定値)、

画面の左上を起点として、

  • エレメントの上端(top)までのピクセル数がtop
  • エレメントの下端(bottom)までのピクセル数がbottom
  • エレメントの左端(left)までのピクセル数がleft
  • エレメントの右端(right)までのピクセル数がright

topbottomは起点より上にある場合はマイナスの値
leftrightは起点より左にある場合はマイナスの値

である。

特定の要素が画面に完全に表示されたとき=要素の下端が画面下端より上にあるとき

なので、

// ブラウザによるドキュメント部分の定義の違いを吸収
var d = window.document.documentElement || document.body.parentNode || document.body;

// (要素の下端の座標) < (画面の下端の座標)
oRect.bottom < d.clientHeight

という条件になる。分かりやすくまとめると

var elem = document.getElementById('coupon');
var oRect = elem.getBoundingClientRect();
var d = document.documentElement || document.body.parentNode || document.body;
if (oRect.bottom < d.clientHeight) {
  // 実行する処理
}

ということになる。

コード

実際のGoogleアナリティクスのイベントトラッキングとして実装すると以下のようになる。
Googleアナリティクスのトラッキングタグとの前後関係は問わない(どこに設置してもいい)。

// 処理で使った変数や関数がグローバルを汚染しないようにクロージャで
(function(){
  // DOM指定するので読み込み完了後に実行
  // このタイミングだとGoogleアナリティクスのトラッキングタグとの前後関係は問わなくなる
  document.addEventListener('DOMContentLoaded', function(){
    // スクロール時の処理を関数で定義
    function f() {
      if (!window.scrolled) {
      // 採用するドキュメントの定義
        var d = document.documentElement || document.body.parentNode || document.body;
        // 座標オブジェクトを取得
        var oRect = document.getElementById('#coupon_pc').getBoundingClientRect();
        // 全面が画面に表示されたらフラグを立てる
        if (oRect.bottom < d.clientHeight) {
          window.scrolled = true;
        }
        ga('send', 'event', 'coupon', 'scroll', 'inview');
      }
    }
    window.scrolled = false;
    window.addEventListener('scroll', f, false);
  }, false);
}());

実際には

  • 複数のGAのトラッカーを呼び出している
  • SPとPCでエレメントIDが違う

ケースだったので

// おまじない
if (typeof ga !== 'function') {
  var gaAlias = window['GoogleAnalyticsObject'] || 'ga';
  window[gaAlias] = window[gaAlias] || function() {
    (window[gaAlias]['q'] = window[gaAlias]['q'] || []).push(arguments);
  };
}

// 処理で使った変数や関数がグローバルを汚染しないようにクロージャで
(function(){
  // DOM指定するので読み込み完了後に実行
  document.addEventListener('DOMContentLoaded', function(){
    // スクロール時の処理を関数で定義
    function f() {
      if (!window.scrolled) {
        // 採用するドキュメント
        var d = document.documentElement || document.body.parentNode || document.body;
        // 座標オブジェクトを取得(SPとPCで違う要素)
        if (window.navigator.userAgent.toLowerCase().indexOf('mobi') > -1) {
          var oRect = document.getElementById('#coupon_sp').getBoundingClientRect();
        } else {
          var oRect = document.getElementById('#coupon_pc').getBoundingClientRect();
        }
        // 全面が画面に表示されたらフラグを立てる
        if (oRect.bottom < d.clientHeight) {
          window.scrolled = true;
        }
        // フラグが立ったタイミングで
        if (window.scrolled){
          // イベント検出を無効に
          window.removeEventListener('scroll', f, false);
          // GTMが作ったトラッカーを呼び出してsend event
          ga(function(trackingId) {
            return function(){
              var trackers = ga.getAll().filter(function(tracker) {return tracker.get('trackingId') == 'trackingId'});
              if(trackers.length > 0) {
                trackers[0].send('event', 'coupon', 'scroll', 'inview');
              }
            };
          }('UA-99999999-1'));
        }
      }
    }
    window.scrolled = false;
    window.addEventListener('scroll', f, false);
  }, false);
}());

というコードになった。

用途

このスクリプトは

  • クーポンの表示
  • テキストのどの段落まで読了したか

をカウントのに使える。これらは結構実現したい用途ではないだろうか?

Googleアナリティクス関連Tips

イベント計測

ページビュー計測

eコマース計測

Google の記事一覧