Waiting for Godot
Once upon a time, I faced a situation where a web application relied upon custom link tracking heavily. Unfortunately, the application could send tracking values before the s_code loaded.
While I doubt this occurs too often, I think there is value in this example. Such as the future posts I have planned which use this example as a component. Finally, if the code looks a bit odd, its a modified version of the JavaScript Module Pattern.
Implementation, Live Example, Example Code:
Utilizing the tracking buffer is fairly simple, the earlyTracking function can stand alone. However, for an implementation without modifying the earlyTracking function, three things are required.
- objTrackingVariables and trackData are required
- Custom link tracking to be buffered must use trackData()
- sendTracking() within trackData() must be configured to send data to Omniture
Try the Example or See the Code from the Example
Breaking Down the Code:
First, an object to put everything in and keep things clean.
var customTrack = {};
Next an object to keep variables we want to persist. Some parts are for future posts.
customTrack.objTrackingVariables = {
strInteractTrackVars: 'props, eVars, events',
blnBufferOn: false,
blnLoadFail: false,
arrTrackingArray: []
};
Expanding this part in future posts.
customTrack.trackData = (function () {
//Expanding on this part later
function sendTracking(strTrackType, strTrackValue){
//tracking is prepared then sent here
}
return function (strTrackType, strTrackValue) {
if ('undefined' !== typeof(s) && !customTrack.objTrackingVariables.blnBufferOn) {
sendTracking(String(strTrackType), String(strTrackValue));
} else if (!customTrack.objTrackingVariables.blnLoadFail) {
customTrack.earlyTracking(String(strTrackType), String(strTrackValue));
}
};
}());
The fun for this post starts here.
customTrack.earlyTracking = (function () {
Creating a object to hold values we want to persist, and only accessible inside the earlyTracking function.
var objEarlyBuffer = {
blnDataStored: false,
blnIntervalOn: false,
intIntervalCounter: 0,
arrEarlyArray: [],
intervalCheckS: null
};
This function sends the tracking values we have stored in the ‘buffer’ array.
function sendEarlyTracking() {
var intEarlyBufferCounter = -1;
var arrTrackLink = [];
while (++intEarlyBufferCounter < objEarlyBuffer.arrEarlyArray.length) {
arrTrackLink = String(objEarlyBuffer.arrEarlyArray[intEarlyBufferCounter]).split("|");
customTrack.TrackData(String(arrTrackLink[0]), String(arrTrackLink[1]));
}
objEarlyBuffer.blnDataStored = false;
objEarlyBuffer.arrEarlyArray = [];
objEarlyBuffer.blnIntervalOn = false;
if ('undefind' !== typeof(customTrack.objTrackingVariables.blnBufferOn)) {
customTrack.objTrackingVariables.blnBufferOn = false;
}
clearInterval(objEarlyBuffer.intervalCheckS);
}
After the 100ms interval is created (next function), this function checks if ‘s’ is defined and clears the interval after two minutes if ‘s’ is not seen.
function sReady() {
objEarlyBuffer.intIntervalCounter++;
if (objEarlyBuffer.blnIntervalOn && objEarlyBuffer.intIntervalCounter > 1200) {
clearInterval(objEarlyBuffer.intervalCheckS);
objEarlyBuffer.blnIntervalOn = false;
customTrack.objOmniVars.blnBufferOn = false;
customTrack.objOmniVars.blnLoadFail = true;
}
if (objEarlyBuffer.blnIntervalOn && 'undefined' !== typeof(s)) {
clearInterval(objEarlyBuffer.intervalCheckS);
objEarlyBuffer.blnIntervalOn = false;
if ('undefind' !== typeof(customTrack.objTrackingVariables.blnBufferOn)) {
customTrack.objTrackingVariables.blnBufferOn = false;
}
sendEarlyTracking();
} else {
return false;
}
}
Below is the functionality for the ‘public’ method.
function bufferEarlyTracking(strTmpTrackString) {
if (!objEarlyBuffer.blnIntervalOn) {
if ('undefind' !== typeof(customTrack.objTrackingVariables.blnBufferOn)) {
customTrack.objTrackingVariables.blnBufferOn = false;
}
objEarlyBuffer.blnIntervalOn = true;
objEarlyBuffer.intervalCheckS = setInterval(sReady, 100);
}
objEarlyBuffer.blnDataStored = true;
objEarlyBuffer.arrEarlyArray.push(strTmpTrackString);
if ('undefined' !== typeof(s) && objEarlyBuffer.arrEarlyArray.length > 0 && !objEarlyBuffer.blnIntervalOn) {
sendEarlyTracking();
}
}
Wrapping things up.
return function (strTrackType, strTrackValue) {
bufferEarlyTracking(String(strTrackType) + "|" + String(strTrackValue));
};
}());