Skip to content

Instantly share code, notes, and snippets.

@dustinlarimer
Last active December 19, 2016 23:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dustinlarimer/04f02384cc28ea3a9f409fc57316e7c6 to your computer and use it in GitHub Desktop.
Save dustinlarimer/04f02384cc28ea3a9f409fc57316e7c6 to your computer and use it in GitHub Desktop.
Scroll-tracking with an unload listener
<html>
<head>
<meta charset="utf-8">
<script src="http://d26b395fwzu5fz.cloudfront.net/keen-tracking-1.0.1.js"></script>
</head>
<body style="height: 9000px;">
<h1>Open your developer console</h1>
<a href="./index.html">Test Page Unload</a>
<script>
/*
Define client
*/
var client = new Keen({
projectId: 'YOUR_PROJECT_ID',
writeKey: 'YOUR_WRITE_KEY'
});
// Log attempts
client.on('recordEvent', console.log);
Keen.debug = true;
Keen.ready(function(){
// Set listener to sample engagement on page unload
// Define data model for 'page-unload' events here
setUnloadListener(function(){
return {
scroll_info: sampleScrollState()
};
});
});
/*
Define scroll-handler
*/
var winScroll = Keen.utils.listener('window');
var pixel = 0, pixel_max = 0;
winScroll.on('scroll', sampleScrollState);
var scrollSampler = setInterval(function(){
console.log(sampleScrollState());
}, 2000);
/*
Scroll-depth sampling
*/
function sampleScrollState() {
pixel = getScrollOffset() + getWindowHeight();
if (pixel > pixel_max) {
pixel_max = pixel;
}
return {
'pixel': pixel,
'pixel_max': pixel_max,
'ratio': parseFloat( Number(pixel / getScrollableArea()).toFixed(2) ),
'ratio_max': parseFloat( Number(pixel_max / getScrollableArea()).toFixed(2) )
}
}
function getWindowHeight() {
return window.innerHeight || document.documentElement.clientHeight;
}
function getScrollOffset() {
return (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
}
function getScrollableArea() {
var body = document.body, html = document.documentElement;
return Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight ) || null;
}
/*
Interrupt unload to perform synchronous request
*/
function setUnloadListener(dataModelHandler){
console.log('Called: setUnloadListener()')
var attachEvent, whichEvent;
var handler = function(){
handleUnloadEvent(dataModelHandler);
};
if (window.onpagehide || window.onpagehide === null) {
window.addEventListener('pagehide', handler, false);
}
else {
attachEvent = window.attachEvent || window.addEventListener
whichEvent = window.attachEvent ? 'onbeforeunload' : 'beforeunload';
attachEvent(whichEvent, handler);
}
}
function handleUnloadEvent(dataModelHandler){
var request = getXHR();
var url = client.url('events', 'page-unload');
if (request) {
url += '?api_key=' + client.writeKey();
url += '&data=' + encodeURIComponent(
btoa(
JSON.stringify(
dataModelHandler()
)
)
);
request.open('GET', url, false);
request.send(null);
}
}
function getXHR() {
if (window.XMLHttpRequest && ('file:' != window.location.protocol || !window.ActiveXObject)) {
return new XMLHttpRequest;
} else {
try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
}
return false;
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment