On a single page webapp, I've implemented the google async tracker. I created a class to be able to make some simple calls to be able to track users across the site:
var GoogleAnalytics = {
config : {
'account':'UA-XXXXXXXX-X'
},
init : function(){
var _gaq = _gaq || [];
this.tracker = _gaq;
_gaq.push(['_setAccount',this.config.account]);
(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);
})();
},
doAsyncRequest : function(arr){
if(!this.tracker) this.init();
this.tracker.push(arr);
},
trackPageView : function(url){
var args = ['_trackPageview'];
if(url) args.push(url);
this.doAsyncRequest(args);
},
trackEvent : function(category,action,label,value){
var args = ['_trackEvent',category,action];
if(label) args.push(label);
if(value) args.push(value);
this.doAsyncRequest(args);
},
trackCustom : function(index,name,value,scope){
var args = ['_setCustomVar',index,name,value];
if(scope) args.push(scope);
this.doAsyncRequest(args);
}
}
When the app is loaded, I create an instance of the above like so:
var that = this;
require(['js/plugins/GoogleAnalytics'],function(ga){ that.ga = GoogleAnalytics; });
it uses require.js to load in the above script, and assign this.ga to it.
Then, when trying to track a page view, I use this:
var that = this
$.each(payload.events,function(index,event){
if(event.eventType == 'page'){
var pagePath = event.currentURL.replace(/^(https?:\/\/[^\/]+)/i,'');
that.ga.trackPageView(pagePath);
} else {
that.ga.trackEvent(event.eventType,event.elementClass);
}
});
payload.events just contains an array of events. an event looks something like this for a page view: {'eventType':'page','currentURL':'http://www.testurl.com/#!/testing/test/test'}
This all gets to google ok, but in analytics, it tracks a page view as a unique page visit, and doesn't track across the users' visit. So my analytics are somewhat useless, as it looks like I have WAY more visits than I really do, and a ridiculous bounce rate.
Is there something I'm missing that would fix this and make it track page views like a normal analytics install?
Frankie got this one right in my comments, I believe the issue was with require.js making a new scope and something breaking there.
Related
I am trying to use the History API to allow me to use the back and forward buttons when loading content dynamically. Here is the code I am using, and an example of the state object I am using too.
How I am using the state object and pushstate()
var stateObj = {Content : homeSection.innerHTML, "Product" : detail.Name, Title : title.innerHTML, Section:"dynamicArticle"};
window.history.pushState(stateObj, "", detailName);
window.addEventListener('popstate', function(event) {
updateContent(event.state);
});
Function used:
function updateContent(stateObject) {
if (stateObject){
homeSection = document.getElementById(stateObject.Section);
homeSection.innerHTML = stateObject.Content;
title.innerHTML = stateObject.Title;
var items = document.querySelectorAll(".homeItem");
if(items){
for(i=0; i<items.length; i++){
items[i].addEventListener("click", selectedProduct);
}
}
checkoutButton = document.getElementById('checkoutButton');
if(checkoutButton){
checkoutButton.addEventListener('click', function(){
displayCheckout();
});
}
basketButton = document.getElementById("basketButton");
quantityInput = document.getElementById("productQuantity");
if(basketButton){
basketButton.addEventListener('click', clicked);
basketButton.addEventListener('click', updateBasketNumber);
quantityInput.value = "1";
}
searchSort = document.getElementById("sort");
if(searchSort){
var items = document.querySelectorAll(".searchResult");
for(i=0; i<items.length; i++){
items[i].addEventListener("click", selectedProduct);
}
searchSort.addEventListener("change", function(){
sort = searchSort.value;
searchItem(e, sort);
});
}
}
else{
return;
}
}
What I am struggling with is that if I navigate to one of the pages using the pushState() and I try to reload the page, as you would expect the page cannot be found.
I am asking if there is a way to allow a reload or for someone to navigate to the URL without it giving an error, and giving the correct content
Just like #jon-koops pointed in the comment you need to configure your server to redirect requests to the same page where all you links branch.
If you are using apache 2.2.16+ it get's as simple as:
FallbackResource /index.html
This will rewrite all URL’s to a single entry point that is index.html page.
Other solutions depend on the server you are running.
I have a really strange behiavour with the loading of a SWF file: the buttons on it are working on the first load, but if I reload the page they don't work anymore, even if I empty my cache or force SWF reload by appending a random parameter at the end of the URL. The buttons are generated from a XML file called in the init function.
Here is how I call my swf :
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script
<script type="text/javascript">
// <![CDATA[
window.onload=function(){
var _time = (new Date()).getTime();
var params = {wmode: "transparent", src: "http://www.mywebsite.com/sites/default/files/medias/map/monde.swf?" + _time};
var flashvars = {site: "/fr"};
swfobject.embedSWF("http://www.mywebsite.com/sites/default/files/medias/map/monde.swf?" + _time, "flashContent", 920, 450, "10", false, flashvars, params);
};
// ]]>
</script>
<div id="flashContent"> </div>
The only way to get the buttons back is to edit the source in Firebug, change the SWF URL with something random and change it back so the URL is loaded again (it's not working on the first try, I have to do it few times before it works).
I don't have any cache on the SWF and on the XML I'm calling from AS3, so I don't understand how I can have such a random behaviour :
Here is the relevant parts of the AS3 script :
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
var site:String = "";
if (this.loaderInfo.parameters.site != undefined)
site = this.loaderInfo.parameters.site;
_uLoader = new URLLoader();
_uLoader.addEventListener(Event.COMPLETE, _initMap);
var httpHeader : URLRequestHeader = new URLRequestHeader("pragma", "no-cache");
var httpRequest : URLRequest = new URLRequest(site+"/ajax/mywebsite_tools/list_master");
httpRequest.requestHeaders.push(httpHeader);
httpRequest.method = URLRequestMethod.GET;
httpRequest.data = new URLVariables("time="+Number(new Date().getTime()));
_uLoader.load(httpRequest);
_supportContinent = new MovieClip();
this.addChild(_supportContinent);
}
private function _initMap(e:Event):void
{
var cs:mywebsiteSingleton = mywebsiteSingleton.getInstance();
var xml:XML = new XML(_uLoader.data);
cs.xml = xml;
btRetour.buttonMode = true;
btRetour.mouseChildren = false;
btRetour.txt.text = xml.retour.text();
btRetour.gotoAndStop('OUT');
addEventListener(mywebsiteEvent.CONTINENT_CLICK, _contientClick);
btRetour.addEventListener(MouseEvent.CLICK, _retourMonde);
btRetour.addEventListener(MouseEvent.ROLL_OVER, _over);
btRetour.addEventListener(MouseEvent.ROLL_OUT, _out);
}
Figured it out. It was rather trivial in fact, the _initMap() function was randomly called before or after my buttons appear on the timeline. So if i get the xml too fast, the _initMap() function try to refer to a button that doesn't exist.
Fixed it with something a bit dirty, but anyway it works :
private function _initMap(e:Event):void
{
if(!btRetour || btRetour == null || !btRetour.hasOwnProperty("buttonMode")) {
setTimeout(_initMap, 500, e);
return;
}
// ...
}
We're having an issue with Virtual Pageviews not being recorded in Analytics.
We have the following tracking code at the bottom of the page (not the async version)
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXXXX-3']);
_gaq.push(['_trackPageview']);
(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>
And for the individual virtual pages we're trying to track we have the following code:
$(".contact_sub a").click(function ()
{
//instantiate it
var pageTracker = _gat._getTracker("XX-XXXXXXXX-1");
//get company name
var companyName = $(this).parents(".resultContainer").find("H2").text();
//track this click event as a page view
pageTracker._trackPageview("/click-tracking/company/" + companyName + ".html");
$(".window_" + $(this).attr("rel")).dialog({
modal: true,
width: "350px"
});
return false;
});
In Firebug NET tab we can see the correct call be sent out to google and the Image is returned. The parameters being sent out are right too.
Problem is nothing is showing up in Analytics. We've done this for another project and it worked just fine.
I just noticed now that in the two lines that deal with getting an instance of the tracker there's one tiny difference and that's the last number. One is a 1 and the other is a 3. Not sure why that is that way.
Any help would be great.
Thanks
Jacques
The getTracker needs your website ID, as specified in google analytics. They should be the same basicly, those pageview are now being registered at another website. So just change the 3 in a 1.
I wrote a FireFox addon which has a button on the toolbar.
On click event, I am trying to find the EMBED element and try to call pauseVideo() on it, but it doesn't work.
I am sure the object I get is the EMBED so no doubt about that, because I display the 'src'
var p1 = content.document.getElementById("movie_player");
window.alert(p1.src);
The problem is pauseVideo() doesn't work:
try
{
p1.pauseVideo();
}
catch(e)
{
window.alert(e); // this gives 'pauseVideo() is not a function'
}
Also, the 'allowscriptaccess' attribute is set to 'always'.
Any idea why it doesn't work? I am out of ideas.
Thanks!
Make sure the enablejsapi is set.
https://developers.google.com/youtube/player_parameters#enablejsapi
You need to use postMessage to communicate with Youtube player, something like this:
var doc = content.document;
var scpt = doc.getElementById("uniq_script_id");
if (!scpt) {
scpt = doc.createElement("script");
scpt.type = "text/javascript";
scpt.id = "uniq_script_id";
var code = [
'window.addEventListener("message", function(e) {',
' var cmd = e.data;',
' var player = document.getElementById("movie_player");',
' player[cmd]();',
'}, false);'
].join('\n');
scpt.textContent = code;
doc.body.appendChild(scpt);
}
window.postMessage("pauseVideo", "*");
Little bit confused... I am trying to track mailto links being clicked, but constantly 'pageTracker is not defined' is shown. I have the following code just before my end body tag ()
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-000000']); // This is my account number, I have added the zeros in this editor
_gaq.push(['_trackPageview']);
(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 I am using this in my mailto links
hello#mydomain.co.uk
I cannot see why its not working? Any help would be appreciated
The new Async Google Analytics code (that you're using) works a bit differently than the non-Async. Any time that you want to call a method on pageTracker you simply push a "message" onto the "_gaq" queue.
hello#mydomain.co.uk
Although, tracking a mailto link may work better as an event:
hello#mydomain.co.uk
For more info take a look at the Async Tracking Users Guide.
We can also add:
//mantain syntax between old and new asynch methods
//http://code.google.com/apis/analytics/docs/tracking/asyncUsageGuide.html#Syntax
function _pageTracker (type) {
this.type = type;
this._trackEvent = function(a,b,c) {
_gaq.push(['_trackEvent', a, b, c]);
};
}
var pageTracker = new _pageTracker();
in new code to mantain old code in pages.
Here is the code :
onClick="_gaq.push(['_trackEvent', 'pdf', 'download', '/pdf/myPdf'])">myPdf</a>
I needed a way to tack downloading PDFs too and heres what I used:
Download Brochure
For more info about _trackEvent, heres the API Doc page