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(){

    // 発火するページを指定
    if(/^\/path\/to\/coupon\.html/.test(window.location.pathname)){
        // 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);
    }
}());

実際には

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

ケースだったので

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

// 処理で使った変数や関数がグローバルを汚染しないようにクロージャで
(function(){
    // 発火するページを指定(これはトリガーで設定してもいい)
    if(/^\/path\/to\/coupon\.html/.test(window.location.pathname)){
        // 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();
                                for (var i = 0, j = trackers.length; i < j; i++) {
                                    var t = trackers[i].get('trackingId');
                                    if (trackers[i].get('trackingId') == trackingId) {
                                        trackers[i].send('event', 'coupon', 'scroll', 'inview');
                                        break;
                                    }
                                }
                            };
                        }('UA-99999999-1'));
                    }
                }
            }
            window.scrolled = false;
            window.addEventListener('scroll', f, false);
        }, false);
    }
}());

というコードになった。

用途

このスクリプトは

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

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

Googleアナリティクス関連Tips

イベント計測

ページビュー計測

eコマース計測