I'm working on a project here that will store some info in Google Analytics custom variables. The script I'm building out needs to detect if GA has loaded yet before I can push data to it. The pr开发者_StackOverflow中文版oject is being designed to work across any kind of site that uses GA. The problem is reliably detecting if GA has finished loading or not and is available.
A couple of variabilities here:
There's multiple methods of loading GA. Older scripts from the Urchin days up to the latest asynchronous scripts. Some of these are inline, some are asynchronous. Also, some sites do custom methods of loading GA, like at my job. We use YUI getScript to load it.
Variable-variable names. In some scripts, the variable name assigned to GA is
pageTracker
. In others, its_gaq
. Then there's the infinity of custom variable names that sites could be using for their implementation of GA.
So does anyone have any thoughts on what might be a reliable way to check if Google Analytics is being used on the page, and if it's been loaded?
This, you can put the code above/before the Google Analytics Tracking Code :
function check_ga() {
if (typeof ga === 'function') {
console.log('Loaded :'+ ga);
} else {
console.log('Not loaded');
setTimeout(check_ga,500);
}
}
check_ga();
Demo: http://jsbin.com/rijiyojume/edit?html,console
Or If you can run script after the Google Analytics Tracking Code :
ga(function(tracker) {
console.log(tracker.get('clientId'));
});
Demo: http://jsbin.com/wiqategifo/1/edit?html,console
Ref: #ready-callback
I'm too lowly to respond to Annie's answer which works but has syntax errors. Analytics names have underscore first and the setTimeout() syntax was backwards (and incomplete). It should be this:
function checkIfAnalyticsLoaded() {
if (window._gat && window._gat._getTracker) {
// Do tracking with new-style analytics
} else if (window.urchinTracker) {
// Do tracking with old-style analytics
} else {
// Probably want to cap the total number of times you call this.
setTimeout(checkIfAnalyticsLoaded, 500);
}
}
function checkIfAnalyticsLoaded() {
if (window._gaq && window._gaq._getTracker) {
// Do tracking with new-style analytics
} else if (window.urchinTracker) {
// Do tracking with old-style analytics
} else {
// Retry. Probably want to cap the total number of times you call this.
setTimeout(checkIfAnalyticsLoaded, 500);
}
}
Here is how I did it:
var ga = window[window['GoogleAnalyticsObject'] || 'ga'];
if (typeof ga == 'function') {
// call ga object here
ga('send', 'event', 'Social Share Button', 'click', 'facebook');
}
ECMA2015 style
let checkIfAnalyticsLoaded = () => {
return new Promise((resolve, reject) => {
let timeStart = Date.now();
const TIMEOUT = 3000;
let _isLoaded = function() {
if (Date.now() - timeStart > TIMEOUT) {
reject('Timeout. Google analytics not injected!');
return;
}
if (window.ga && ga.create) {
resolve(ga);
return;
} else {
setTimeout(_isLoaded, 500);
}
};
_isLoaded();
});
}
checkIfAnalyticsLoaded()
.then((result => {
console.log('LOADED', result);
}))
.catch(console.error);
None of the above methods worked well for me. Maybe because I am loading GA through GTM, not sure. But this simple method did work from the console for me :
ga.loaded
If you are trying to check from within your script, you may need to wait a bit as GA is loaded after doc ready :
var t = setTimeout(function(){
console.log(ga.loaded);
}, 999);
Adjusted version to wait for Google Analytics to not only have finished loading, but als have generated the clientId (in case you need it, like I do). Also added a cap on amount of retries (20).
var retryCounter = 0;
function checkIfAnalyticsLoaded() {
if ((typeof ga === 'function' && ga.loaded) || retryCounter++ > 20) {
// ga() puts your method in the Command Queue,
// which is applied after GA is done with initialization
ga(yourFunctionHere());
} else {
// Retry.
setTimeout(checkIfAnalyticsLoaded, 500);
}
}
// Auto load
(function () {
checkIfAnalyticsLoaded();
})();
I'm using this, but I built a helper function out of it that lets me pass in a function and arguments, and they're called when Google Analytics is loaded. It checks once every half second, and stops checking after a minute if Google Analytics hasn't loaded. I thought this might be helpful for others.
Usage:
function add(a,b){alert(a + ' + ' + b + ' = ' + (a+b));}
_mygaq(add,1,2);
Code:
function _mygaq(fn) {
this._count = this._count || 0;
this._running = this._running || false;
this._q = this._q || [];
if(arguments.length>0){
this._q.push({"f":fn,"p":Array.prototype.slice.call(arguments,1)});
} else {
this._count++;
}
if ((window._gat && window._gat._getTracker) || window.urchinTracker) {
this._count = 0;
this._running = false;
while (this._q.length > 0){
var _innr = this._q[0];
this._q = this._q.slice(1);
_innr.f.apply(_innr.f, _innr.p);
}
} else {
if( (arguments.length==0) || (!this._running && arguments.length>0)){
if(this._count < 120) setTimeout('_mygaq()', 500);
this._running = true;
}
}
}
I find the most elegant solution to be something like this:
const isAnalyticsLoaded = Promise.race([
new Promise(resolve => setTimeout(() => resolve(), 10000)),
new Promise(resolve => {
const isLoaded = () => window.ga && window.ga.loaded
? resolve()
: setTimeout(isLoaded, 200)
isLoaded()
})
])
The first promise is only for timeout in case ga never gets loaded. You can of course reject
instead of resolve
if that's what you need.
Simply check this object after window load event.
if(window.google_tag_manager){ /*It's loaded!*/ }
I have a different solution for this if anyone cares to try it out. This assumes your Google Analytics Object is 'ga'. Change your timeout and max tries to suit your application.
<script type="text/javascript">
var counter = 1;
function checkIfAnalyticsLoaded() {
if (window.ga) {
//LOADED!
} else {
counter = counter + 1;
if (counter < 6){
setTimeout('checkIfAnalyticsLoaded()', 200);
} else {
//LOADED!
}
}
}
window.onload = checkIfAnalyticsLoaded();
</script>
you may also look into the new Asynchronous Tracking and then you wont need to check you can just do whatever and it will send the data as soon as it loads...
精彩评论