console.trace();

旬なものから枯れたテクノロジーまで

GoogleAnalyticsのイベントトラッキングで盛大にはまった

タイトル通り盛大にはまりました。 まさかまさかこんな事があろうとは、 たかがひとつのイベントトラッキングではまるとは。。。

みなさんご存知、GoogleAnalyticsを使用時でユーザーイベントをトラッキングしたい場合は

<!-- ga.jsを読み込んでる想定 -->

<a id="test" href="http://test.com">外部サイトへ</a>
<script>
(function () {
    var anc = document.getElementById('test');

    anc.addEventListener('click', function () {
        _gaq.push(['_trackEvent', 'category', 'act']);
    }, false);
}());
</script>

大体こんなコードになりますよね。

でもこれ実はブラウザによっては動くかわからない。

え?なんで?と大はまり。 色々調べたのですがどうやらページ遷移の際にunloadが早く走ってしまうからみたいです。

管理画面上に正確なデータを表示するためには、 ビーコンと呼ばれる1px x 1pxのgifを送信して初めてtrackEventを正常に計測されます。 これをビーコンと呼びます。 がしかし、ブラウザによってはこのビーコンが送られる前にunloadが走ってしまい、 計測が正常に行われなケースがあるのです。特に顕著なのはFireFox

Googleではこの問題に対する回答が下記で発表されています。

https://support.google.com/analytics/answer/1136920?hl=en

ほうほう、こうすれば解決できるのね!と早速試してみた。

・・・ 先生、問題回避できません!!!

コードを覗いてみると、どうやら遅延を意図的に発生させて回避させている模様。 これだとIEやChrome等は回避出来てもFireFoxは回避出来なかった。

うーんうーんと四苦八苦したところ、あまいいい方法とは言えませんが、 FireFoxの問題はこうすれば完全に回避できる事が判明。

<script>
(function () {
    var anc = document.getElementById('test');
    var flgEmulate = false;

    anc.addEventListener('click', function (e) {
        var elm;

        if (flgEmulate) {
            flgEmulate = false;
            return;
        }

        elm = e.target;

        while (elm.tagName !== 'A') {
            elm = elm.parentNode;
        }

        e.preventDefault();

        setTimeout(function () {
            var evnt = document.createEvent('MouseEvents'); 
            
            evnt.initEvent('click', false, true);

            flgEmulate = true;

            elm.dispatchEvent(evnt);        
        }, 100);    
    }, false);
}());
</script>

うん、我ながら冗長なコードですね、はい。

内容は、clickを一時的に無効化し、擬似的にエミュレートしたclickイベントを発生させてからunloadを発生させるというもの。

※ただし、clickを擬似的に発生させることにより、ページの既存JavaScriptとの競合なども起こりうるのでご利用は計画的に!

※ほかに何かいい方法がをご存知の方がいらしたら教えていただきたいです。

なにはともあれ動いてすっきり。

追記 7/19 変数名間違っていたのでコード修正しました。