freelance developer of javascript, python and more!

Facebook have recently (very quietly) added the FB.Canvas.getPageInfo and FB.Canvas.scrollTo methods to their JavaScript SDK. These used to exist in their old SDK, but it’s taken a year for it to appear in the new one! This is good news to me for the following reason.

If you wanted to create a message dialog popup in an application, you had no guarantee that it would be visible on the screen when it was shown as you have no idea where the user’s viewport is. Most JavaScript popup libraries try to position the dialog in the centre of the screen by looking at the window’s scroll position. Unfortunately when creating a Facebook Application you’re operating inside a cross-domain iframe so that information isn’t directly available, the best you could do is put it somewhere near where the user clicked.

With the introduction of the getPageInfo method, we can now access it and start positioning things where the user can see them. For example, to position a div at the top of the viewport using jQuery, try this:

var pageInfo = FB.Canvas.getPageInfo();
var offset = parseInt(pageInfo.scrollTop) - parseInt(pageInfo.offsetTop);
$("#element").css({
    // use Math.max so that the element isn't positioned above the top of the page
    top: Math.max(offset, 0)
});

You might have noticed that I’ve surrounded the page info properties with the parseInt function. This is because they are stored by the SDK as strings so must be parsed before you can use them in mathematical operations.

Bonus: canvas.pageInfoChange Event

This isn’t documented on the Facebook Developer website, so may be change without warning, however while poking around the SDK code for pageInfo, I noticed a pageInfoChange event gets dispatched after the pageInfo object is updated. This lets us listen for when the user scrolls the browser window and update the display accordingly, for example by keeping the dialog window in the center of the user’s screen.

FB.Event.subscribe("canvas.pageInfoChange", function(event){
    $("#dialog").animate({
        top: Math.max(parseInt(event.scrollTop) - parseInt(event.offsetTop) +
                ((parseInt(event.clientHeight)-$("#dialog").outerHeight())/2), 0)
    }, "fast");
});

Edit: Since writing this, Facebook have now removed the pageInfoChange event. You can create your own version that polls Facebook for the latest canvas data. See this question on StackOverflow for more info.

Final Note

Because the page info object is updated via cross-domain ajax calls, it isn’t always up to date, and is only dispatched a couple of times per second, not at the same rate as the equivalent window.onscroll method would be called. Therefore, you can’t use it to lock an element to a specific position on the screen (emulating position: fixed,) that’s why I use jQuery animation to update the position of the box in the above example, as it avoids the dialog jumping around the page.

§62 · May 30, 2011 · Facebook · Tags: , , · [Print]