This is old, but I'm faced with the same issue :
when using simple custom <button> instead of "official" FB button, the login popup window opens on extreme right of screen.
I think the official button (wich is complex : a complete html page with JS) makes use of the SDK for centering the popup. I couldn't manage to use the SDK for centering popup with a custom button (if someone does, tell us!).
The FB.login() function doesn't center popup when fired from custom button.
I found this solution, which works great :
http://permadi.com/2011/04/centering-facebook-oath-login-popup-dialog/
the online demo (view source to see code) :
http://www.permadi.com/tutorial/facebook-js-oauth-popup-centered/index.html
It makes use of FB.getLoginStatus() and NOT FB.login().
It mimics the FB.login function :
- open centered facebook popup with window.open
- check with setInterval if user is logged or not
- when user is finished with facebook, the redirectUrl provided during opening the popup is used by FB go to a blank page we create with only window.close() in it --> it closes the popup
- clearInterval and continue with app code (login, save in data base...)
Below is my JQUERY version of their script with some simplification and improvments :
- simplification : only login button. No logout.
- improvment : load JSK only if user hit the FBlogin button (and only once)
- improvment : prevent user from triggering multiple facebook popup (important)
We kind of recreate the offical FB.login function here:)
But there is some advantages over the offical button :
- we can use a simple
<button> wich is very easy to style
- wich is accessible (try to catch official btn with TAB on keyboard only)
wich loads fast
var fbOpen = 0; // to prevent opening multiple facebook login popup dialog
// otherwhise setInterval is messing things around!
function treatFBresponse() {
FB.init({
appId : 'YOUR_APDD_ID',
status :true, // IMPORTANT, otherwhise if user cancel login (->response.status="unknown), 2nd time -> response.status="NULL" -> no possible login any more!
cookie : true,
version : 'v2.5'
});
FB.getLoginStatus(function(response) {
if (response.status=="connected" && response.authResponse){
FB.api('/me?fields=id,name,first_name,last_name,picture,email', function(response) {
// USER LOGGED into your app and facebook -> console.dir(response); -> log into your app, save in database etc.
}else{
// USER NOT LOGGED into your app
fbOpen = 0; // we let him retry
}
});
}
var gotFBscript = 0; // to load FB JS SDK only once
function fbSDK() {
// SDK NOT LOADED YET
if( !gotFBscript){
console.log('getting FB JS SDK...');
$.ajax({
// OR $.ajaxSetup({ cache: true });
// $.getScript('//connect.facebook.net/en_EN/sdk.js', function(){ gotFBscript = 1 ...
// BUT $.ajax is better I think because it lets you set cache to true locally
url: '//connect.facebook.net/en_EN/sdk.js',
dataType: "script",
cache:true,
success: function() {
gotFBscript = 1;
treatFBresponse();
}
});
// SDK ALREADY LOADED
}else if ( gotFBscript ){
treatFBresponse();
}
};
function facebookPopup() {
var popupWidth=500,
popupHeight=300,
xPosition=($(window).width()-popupWidth)/2,
yPosition=($(window).height()-popupHeight)/2,
loginUrl="http://www.facebook.com/dialog/oauth/?"+
"scope=public_profile,email&"+ // instead of publish_stream
"api_key=YOUR_APDD_ID&"+ // instead of client_id
"redirect_uri=http://www.MY_SITE.COM/path/to/self-closing-empty-page.php&"+
"response_type=token&"+
"display=popup",
fbLoginWindow=window.open(loginUrl, "LoginWindow",
"location=1,scrollbars=1,"+
"width="+popupWidth+",height="+popupHeight+","+
"left="+xPosition+",top="+yPosition),
loginTimer=setInterval( function() { checkLoginWindowClosure(fbLoginWindow, loginTimer), 1000);
};
function checkLoginWindowClosure(fbLoginWindow, loginTimer) {
if (fbLoginWindow.closed)
{
clearInterval(loginTimer);
fbSDK();
}
};
$("#YOUR_CUSTOM_FB_BUTTON").on('click', function() {
if(fbOpen === 0) {
fbOpen = 1;
facebookPopup();
}
});