Thx to Thomas's answer, I created a FacebookApiLoader class to do this. Here's the source, only tested in Firefox 3 at the moment. Hope this helps someone. What this does is looks to see if there are any facebook api dependent elements on the page, and if there are then it will load the facebook api script by inserting it before the body closing tag. This relies on the PrototypeJS library. Call facebookApiLoader.observe() in a page that might require the facebook api.
var FacebookApiLoader = Class.create({
initialize: function() {
this.observer = null
this.observedElement = null
},
apiDependentsVisible: function() {
if (null == this.observedElement) {
// $('facebook-login') is a div in my site that
// is display:none initially. Once it is made
// visible then the facebook api is needed.
// Replace 'facebook-login' with id relevant for your site
this.observedElement = $('facebook-login')
}
return this.observedElement.visible()
},
apiLoadCompleted: function() {
try {
return !Object.isUndefined(FB) && !Object.isUndefined(FB_RequireFeatures)
} catch (e) {
}
return false
},
initAndRequireFeatures: function() {
FB_RequireFeatures(["XFBML"],
function() {
FB.init('secret-put-your-app-value-here','/xd_receiver.html', {})
}
);
},
initFacebookConnect: function() {
new PeriodicalExecuter(function(pe) {
if (this.apiLoadCompleted()) {
this.initAndRequireFeatures()
pe.stop()
}
}.bind(this), 0.2);
},
loadApi: function() {
// Use body for facebook script as recommended in Facebook
// docs not to insert in head as some browsers have
// trouble with it
body = $$('body')[0]
// TODO use https protocol if page is secure
script = new Element('script', { 'type': 'text/javascript',
'src': 'http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php' })
body.appendChild(script)
this.initFacebookConnect()
},
loadApiIfRequired: function() {
if (this.apiDependentsVisible()) {
this.observer.stop()
this.loadApi()
}
},
observe: function() {
if (null == this.observer) {
this.observer = new PeriodicalExecuter(this.loadApiIfRequired.bind(this), 0.2)
}
}
});
// The FacebookApiLoader attributes are lazily loaded
// so creating a new facebookApiLoader
// is as low resource usage as possible
var facebookApiLoader = new FacebookApiLoader();
Then on any page that might need the Facebook api on demand, call
facebookApiLoader.observe();