facebook like click tracking in ajax content

this is how i’ve implemented omniture tracking system with facebook like button
its in form of jQuery plugin.


(function($) {
function loadFbScript(element) {
var script = document.createElement('script');
script.async = true;
script.type = 'text/javascript';
script.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
script.onload = function() {
fbInit(element);
};
script.onreadystatechange = function() {
if (script.readyState == 'loaded' || script.readyState == 'complete') {
fbInit(element);
}
}
document.getElementsByTagName('head')[0].appendChild(script);
}
function fbInit(element) {
if (typeof FB == 'undefined') {
loadFbScript(element);
return;
}
var subscribe = function(url) {
// PUT OMNITURE (or any other) TRACKING HERE
};
if (FB.lnInit) {
FB.Event.clear('edge.create');
FB.Event.subscribe('edge.create', function(url) {
subscribe(element.getAttribute('omniName'), url);
});
FB.XFBML.parse(element);
return;
}
FB.init({
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
xfbml: false // parse XFBML
});
FB.Event.subscribe('edge.create', function(url) {
subscribe(url);
});
FB.XFBML.parse(element);
FB.lnInit = true;
}
$.fn.facebookLike = function(options) {
var defaults = {
width: 'auto',
url: null,
showFaces: true
};
var myOptions = $.extend(defaults, options);
return this.each(function() {
var w = myOptions.width;
if (w == 'auto') {
w = $(this).width();
}
var url;
if (myOptions.url == null) {
url = document.location;
} else {
url = 'http://' + window.location.hostname + myOptions.url;
}
var html = '';
$(this).html(html);
var element = $(this).get()[0];
fbInit(element);
});
}
})(jQuery);

and this is how to use it:

// facebook like without any options
$('#fblike').facebookLike();

// facebook like with custom
$('#fblike').facebookLike({
url: '/custom/relative/link',
showFaces: false
});

code description

loadFbScript() – asynchronously loads facebook code. this function is called just once
fbInit() – check if facebook code is already loaded (if not, loadFbScript() is called. when asynchronously loading is finished, fbInit() is called again)
– first time, FB.init is called. (i am not sure what exactly is happening by calling this, but lets say, facebook init setup happend here)
– subscribe to the click event (ofc you can subscribe to other events as well)
– and finally parse XFBML
– next time fbInit() is called, i clear already subscribed events (this is because facebook push subscribed event functions into the array instead of overwriting them – source) than subscribe again and parse new XFBML (this is useful when new XFBML was loaded via ajax)

look at parse() function – it’s called just for specific element so when you load new content, just the new XFBML should be parsed (already parsed XFBML should stay untouched)

facebook solution and why its wrong

Facebook also provide its own way how to asynchronously load their code, but it has some disadvantages.
1. code is loaded regardless facebook like button is present on the page
2. they are messing with global scope (adding their own fbAsyncInit function to the window object, instead of firing event)
3. if you load facebook like button in the ajax content, you still have to parse XFBML again

Leave a Reply