SiteCatalystで「s is not defined.」を避ける方法

posted May 12, 2011, 8:29 AM by Makoto Shimizu   [ updated May 12, 2011, 10:12 AM ]

SiteCatalystの計測タグでは、

s.pageName = 'top';

のように変数をセットする方法が広く普及していますが、この命令文が実行される前にs_code.jsがロードされていないと「s is not defined.」とJSエラーが発生するのがイマイチです。

JSエラーがよく起こるシチュエーションとしては

  • s_code.jsのロードと変数セットの順番(HTMLソース中の出現の位置関係)が、インクルードなど開発の都合で前後した
  • s_code.jsを設置したサーバーが重くなり、タイムアウトでロード出来なかった
  • s_code.jsを更新した結果、特定の条件でエラーが発生するようになった
また、二つのタグでダブル計測する場合や、他のJSとのコンフリクトを避ける場合などに、オブジェクト名を「s.」以外に変更することがあります。「s.」をあちこちでベタ書きしていると、「s.」を「s2.」や「sc.」などに置換する作業や検証のコストがかかるだけでなく、作業漏れや時差が発生した時に、データが不完全になってしまうリスクがあります。

そこで、解決策について考えてみました。

1. 連想配列で渡す

s.eVar7 = 'cool';
s.prop1 = 'Share/Facebook/Like';
s.t();

は、次のように書くことができます。

var _scq = {
    eVar7: 'cool',
    prop1: 'Share/Facebook/Like'
};
s.t(_scq);
 
s.は一箇所だけになるので、変更が楽になります。
一時的な変数を使わず、
 
s.t({
    eVar7: 'cool',
    prop1: 'Share/Facebook/Like'
});
 
でも良いですね。

2. オブジェクト名を変数に入れる

次のように書くこともできます。
 
var o = 's', w = window;
w[o].eVar7 = 'cool';
w[o].prop1 = 'Share/Facebook/Like';

s.を変更する時は、一箇所だけ直せばokです。

関数の外でもオブジェクト名の変数を使えるようにするためには、上記の例でいう「o」という変数をグローバル変数にする必要があります。

3. エラー回避の判定を入れる

s_code.jsがロードされているかの判定を入れてみます。

var o = 's', w = window, _scq = {
    eVar7: 'cool',
    prop1: 'Share/Facebook/Like'
};
if (typeof w[o] != 'undefined') w[o].t(_scq);
 
...などと考えていると、さらに変数をセットするための汎用的な関数を作りたくなってきました。それについてはまたの機会に。
Comments