This has been bugging me for a few days now and I have not found a way to get it to work. My site is using Jquery, Jquery-Mobile and RequireJS and I want to add Google Analytics to the mix.
My Analytics setup is like so (see also here):
<script type="text/javascript">
var _gaq = _gaq || [];
(function() {
... regular stufff
})();
// bind to pageshow event
$(document).on('pageshow', 'div:jqmData(role="page").basePage', function (event, ui) {
try {
_gaq.push(['_setAccount', 'ID';
_gaq.push(['_gat._anonymizeIp']);
var url = location.href;
try {
if (location.hash) {
url = location.hash;
}
_gaq.push(['_trackPageview', url]);
} catch(err) {}
});
</script>
So I'm listening for the JQM pageshow event to track for Analytics. This snippet is pasted into the end of all pages.
I have fiddled Analytics into requireJS like this:
Main.js:
require.config({
baseUrl: "../js/",
paths: {
"jquery": "libs/jquery/jquery.min",
"jqm": "libs/jquery-mobile/jquery-mobile.min",
"analytics": "https://www.google-analytics.com/ga"
}
require(['order!jquery', 'order!jqm', 'order!analytics', 'app'],
function(jquery, jqm, analytics, App){
App.start();
});
And in App.js:
var start = function() {
require(['order!jquery', 'order!jqm', 'order!analytics'],function() {
// do stuff
});
Problem is, the Analytics snippet is at the end of every page HTML markup, so although I think I have set it up correctly in requireJS with Jquery and Jquery Mobile loading before, I'm still getting an error:
$ is not defined
....ocument).on('pageshow', 'div:jqmData(role="page").basePage', function (event, ui...
when the first page loads.
I guess because HTML markup is outside the reach of require and is parsed before JQM is loaded. Still, there has to be a way to set this up properly.
Question:
Any idea why the error pops up and what I can do about it?
Thanks for help!
EDIT:
Ok. Doing it like this works:
Inside my page header I'm declaring the first part:
<script type="text/javascript">
var _gaq = _gaq || [];
(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>
Then inside my requirejs start function I'm calling the 2nd snippet:
var start = function() {
require(['order!jquery', 'order!jqm'],function() {
var analyticsHasBeenSet;
...
var analyize = function () {
if ( analyticsHasBeenSet != true ){
analyticsHasBeenSet = true;
require(['https://www.google-analytics.com/ga.js'], function (App) {
$(document).on('pageshow', 'div:jqmData(role="page"), function() {
_gaq.push(['_setAccount', '']);
_gaq.push(['_gat._anonymizeIp']);
var url = location.href;
try {
if (location.hash) {
url = location.hash;
}
_gaq.push(['_trackPageview', url]);
} catch(err) { // error catch }
});
});
}
}
analyize();
This way the 2nd snippet will only be executed once Jquery and Jquery Mobile have been loaded. By setting a global variable (I hope) the binding will only be initiated once. So far seems to work.