web-dev-qa-db-ja.com

頭にスクリプトを追加してページを読み込んだ後にGoogleアナリティクスを読み込むと常に機能しない

EUには、ユーザーが同意した後、たとえばクリック、スクロール、またはナビゲートを行うことにより、サードパーティのスクリプトを読み込むことを要求するCookie法があります。そこで、ドキュメントの読み込み後に呼び出される関数を実行して、3つのスクリプトを読み込みます。これはコードです:

enter image description here

問題は、常に機能するわけではなく、常に失敗するわけでもないということです。セッションとアクティビティは表示されますが、他の複数のコンピューターでテストしたときにすべてのアクティビティが分析に保存されたわけではないため、スクリプトをトリガーしない訪問があることも知っています。

常に機能させるために、関数で何を修正する必要がありますか?

25
frenchie
$(document).ajaxComplete(function() {
        var _gaq = _gaq || [];
      _gaq.Push(['_setAccount', 'UA-XXXXX-X']);
      _gaq.Push(['_trackPageview']);

       var loadGoogleAnalytics = function(){
         var ga = document.createElement('script');
           ga.type = 'text/javascript';
           ga.async = true;
           ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';

           var s = document.getElementsByTagName('script')[0];
           s.parentNode.insertBefore(ga, s);
        }
    });
11
Farhad Bagherlo

他の応答は、レガシーであるga.jsをターゲットにしているようですが、あなたの質問はanalytics.js(現在)に向けられているようです。

Analytics.jsスニペットを少し調べると、簡単に答えを見つけることができます(下に、きれいにフォーマットされています):

(function(i, s, o, g, r, a, m) {
  i["GoogleAnalyticsObject"] = r;
  (i[r] =
    i[r] ||
    function() {
      (i[r].q = i[r].q || []).Push(arguments);
    }), (i[r].l = 1 * new Date());
  (a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
  a.async = 1;
  a.src = g;
  m.parentNode.insertBefore(a, m);
})(
  window,
  document,
  "script",
  "https://www.google-analytics.com/analytics.js",
  "ga"
);

ga("create", "UA-XXXXX-Y", "auto");
ga("send", "pageview");

トリックは簡単です。Googleは、グローバルなvar GoogleAnalyticsObjectを作成します。これは、グローバルなGoogleAnalyticsの名前を表す文字列です。デフォルトでは、"ga"

したがって、ロード時に、2つのグローバル変数を作成する必要があります。文字列であるGoogleAnalyticsObjectと、関数(イベントを蓄積するだけで、libがロードされるとこの関数は置き換えられます)であるwindow [GoogleAnalyticsObject]その後、ユーザーがCookieを受け入れると、libをロードでき、完了です:)

5
adz5A

私にうまく機能するこの機能を使用してみてください:

function loadGoogleAnalytics(trackingId) {
                var deferred = $q.defer();

                function loadScript() {
                    var scriptId = 'google-analytics';

                    if (document.getElementById(scriptId)) {
                        deferred.resolve();
                        return;
                    }

                    var s = document.createElement('script');
                    s.id = scriptId;
                    s.innerText = "(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).Push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create', '" + trackingId + "', 'auto');";

                    // most browsers
                    s.onload = initGA();
                    // IE 6 & 7
                    s.onreadystatechange = function () {
                        if (this.readyState == 'complete') {
                            initGA();
                        }
                    }

                    document.getElementsByTagName('head')[0].appendChild(s);
                }

                $window.initGA = function () {
                    deferred.resolve();
                }

                loadScript();

                return deferred.promise;
            }
4

.innerHTML()への呼び出しの代わりに以下を追加してみてください

//...text above...
TheAnalyticsScript.text = ['ga-script-string', 'fb-script.string','hotjar.string'].join('\n');
$('body').append(TheAnalyticsScript);

それが機能するかどうかを教えてください。

4
tyskr

this postをご覧になっている場合は、少し変更して目的を達成できます。

_<script type="text/javascript">
  var _gaq = _gaq || [];
  _gaq.Push(['_setAccount', 'UA-XXXXX-X']);
  _gaq.Push(['_trackPageview']);

   var loadGoogleAnalytics = function(){
     var ga = document.createElement('script');
       ga.type = 'text/javascript';
       ga.async = true;
       ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';

       var s = document.getElementsByTagName('script')[0];
       s.parentNode.insertBefore(ga, s);
    }
</script>
_

次に、ユーザーがCookie Usageの表示に同意するたびにloadGoogleAnalytics()を呼び出すだけです

4
wjvander

これが私の問題です。このソリューションは、デフォルトのスクリプトにパッチを適用して関数を返すだけで、同意が得られた後にのみscriptタグを追加します。ご覧ください:

// for GoogleAnalytics
var loadGA = (function(i, s, o, g, r, a, m) {
  i['GoogleAnalyticsObject'] = r;
  i[r] = i[r] || function() {
      (i[r].q = i[r].q || []).Push(arguments)
    },
    i[r].l = 1 * new Date();

  // call this function after receiving consent
  return function loadGA() {
    a = s.createElement(o),
      m = s.getElementsByTagName(o)[0];
    a.async = 1;
    a.src = g;
    m.parentNode.insertBefore(a, m)
  }
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');

// for Facebook
window.fbAsyncInit = function() {
  FB.init({
    appId: 'your-app-id',
    autoLogAppEvents: true,
    xfbml: true,
    version: 'v2.10'
  });
  FB.AppEvents.logPageView();
};

var loadFB = (function(d, s, id) {
  //- call this function after receiving consent
  return function loadFB() {
    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) {
      return;
    }
    js = d.createElement(s);
    js.id = id;
    js.src = "//connect.facebook.net/en_US/sdk.js";
    fjs.parentNode.insertBefore(js, fjs);
  }
}(document, 'script', 'facebook-jssdk'));

// for HotJar
var loadHJ = (function(h, o, t, j, a, r) {
  h.hj = h.hj || function() {
    (h.hj.q = h.hj.q || []).Push(arguments)
  };
  h._hjSettings = {
    hjid: 1,
    hjsv: 5
  };

  return function loadHJ() {
    a = o.getElementsByTagName('head')[0];
    r = o.createElement('script');
    r.async = 1;
    r.src = t + h._hjSettings.hjid + j + h._hjSettings.hjsv;
    a.appendChild(r);
  }
})(window, document, '//static.hotjar.com/c/hotjar-', '.js?sv=');

// finally when you receive the consent
function onConsentReceived() {
  loadGA();
  loadFB();
  loadHJ();
}

//- meanwhile you can continue using ga(), hj() whatever here...

ローダーはそれぞれ独自のscriptタグに入れることができますが、それらのタグの順序を確認してください。

3
riyaz-ali

分析スクリプト全体を追加するのではなく、常に含めるようにして、次の行を削除することもできます。

ga("send", "pageview");

次に、ユーザーがCookieを受け入れると、上記の同じ行を使用してビーコンを送信する分析関数を起動します。特に指示がない限り、Analyticsは実際にデータを送信しません。それはあなたが試みていることをする最も論理的な方法でしょう。

0
Steve North

あなたのコードが何をするのかを考えると、この関数は:

  1. 文字列で埋められた<script>要素を作成します
  2. <head>に追加します

<head>は、最初のロードでのみロードされることになっていることに注意してください。ブラウザの実装などによっては、訪問者のブラウザの一部が、ページの読み込みが完了した後に追加した<script>タグを無視する場合があります。

あなたがいつ正しいことをしたいのか理解していれば、あなたはしたい:

  1. 追跡スクリプトなしでページをロードするには
  2. 同意のモーダル/ポップアップを表示する
  3. 「同意する」をクリックすると、この機能がトリガーされますwithout a page reload

注:多くのEUウェブサイトは、バックエンドレンダリングを使用してページにトラッキング付きの<script>タグを追加するため、Cookieの同意後にページを再読み込みします。多くの場合、「同意します」をクリックすると、サーバーが送信するWebページを変更するagreed: trueタイプのCookieが保存されます。

リロードを気にしない場合:

  1. ユーザーが同意したときにCookieを設定します
  2. ページをリロードする
  3. バックエンド(php/node/Ruby/whatever)に、このCookieに基づいてスクリプトタグを追加してもらいます

気にするなら

DOMに追加する代わりにトラッキングコードを実行するように関数を変更します。

トラッキングコードを見て、読みやすいコードに分解してください。たとえば、Gaコードは実際には単純です:

var ga = document.createElement('script')
ga.type = 'text/javascript'
ga.async = true
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);

その後

function addTrackers() {

// Execute the tracking things instead of adding them to the DOM

}
0
Mentor