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
};
プロパティの意味は
width
とheight
はエレメントのサイズ(固定値)、
画面の左上を起点として、
- エレメントの上端(top)までのピクセル数が
top
- エレメントの下端(bottom)までのピクセル数が
bottom
- エレメントの左端(left)までのピクセル数が
left
- エレメントの右端(right)までのピクセル数が
right
top
とbottom
は起点より上にある場合はマイナスの値
left
とright
は起点より左にある場合はマイナスの値
である。
特定の要素が画面に完全に表示されたとき=要素の下端が画面下端より上にあるとき
なので、
// ブラウザによるドキュメント部分の定義の違いを吸収
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
イベント計測
- 特定の要素を表示したときにイベントトラッキングする
- 一定以上スクロールしたらイベントトラッキング(PC/スマホ別)
- JavascriptでYahoo!などのタグマネージャに渡すためのイベントを発生させる
ページビュー計測
- [同一URLでフォーム遷移する場合のページビュー計測](/track-form-transition-in-same-url/
- canonicalをページのURLとして自動で採用する実装(計測URLの正規化)
eコマース計測
Google の記事一覧