Facebook New JavaScript Api

  Facebook新的api与旧的相比,有了很大的不同,更加倾向于简约实用,摒弃了旧代码的臃肿繁琐.抛弃了Cross-Domain Receiver Page.旧有的Cross Domain经常有卡在xd_receiver.htm页面没反应的情况发生,新api很好的解决了这个问题.

初始化,登录,授权,FQL,UI等各个方面都有了很大的变化,首先看初始化的不同:

 

Old API:

<script type="text/javascript" src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php">
<script language="javascript">
FB_RequireFeatures(["Api"], function() {
    FB.Facebook.init('api_key', 'xd_receiver.htm', {
        "ifUserConnected": function(){
            // -- connected
        },
        "ifUserNotConnected": function(){
            // -- not connected
        }
    });
});

 

New Api(JS初始化的时候,可以分为两种方式,异步和同步):

异步方式:

<div id="fb-root"></div>
<script language="javascript">
window.fbAsyncInit = function() {
      FB.init({appId: facebook.facebook_app_id, status: true, cookie: true, xfbml: true});
      FB.Event.subscribe('auth.sessionChange', facebook.api_sessionChange);
      FB.getLoginStatus(facebook.api_sessionChange);
};

(function() {
    var e = document.createElement('script');
    e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
    e.async = true;
    document.getElementById('fb-root').appendChild(e);
}());

 

同步方式:

<div id="fb-root"></div>
<script language="JavaScript" src="http://connect.facebook.net/en_US/all.js">

<script language="javascript">
  FB.init({appId: facebook.facebook_app_id, status: true, cookie: true, xfbml: true});
  FB.Event.subscribe('auth.sessionChange', facebook.api_sessionChange);
  FB.getLoginStatus(facebook.api_sessionChange);
</script>
 

新api提供了函数FB.Event.subscribe(),用来检测facebook登录状态变化.

新的api需要用户授权时,调用的函数跟Login一样,只是多了需要授权的参数.

FB.login(function(response) {
  if (response.session) {
    if (response.perms) {
      // user is logged in and granted some permissions.
      // perms is a comma separated list of granted permissions
    } else {
      // user is logged in, but did not grant any permissions
    }
  } else {
    // user is not logged in
  }
}, {perms:'read_stream,publish_stream,offline_access'});

 

新的api在简化了之后,也带来了诸多不便,首先,feed发布的时候,有些许bug,facebook规定在feed长度超过1000的字符的时候,用 post的方式传递数据,不过facebook在传递数据的时候,传错了值,应该将attatch对象json_encode后传递,却直接穿了对象过 去,导致feed发布不了,修正方式是,参考source code修改FB.Content.postTarget函数定义.

 

FB.Content.postTarget = function(opts) {
    var form = document.createElement('form');
    form.action = opts.url;
    form.target = opts.target;
    form.method = 'POST';
    FB.Content.appendHidden(form);

    FB.Array.forEach(opts.params, function(val, key) {
      if (val !== null && val !== undefined) {
        var input = document.createElement('input');
        input.name = key;
        if (typeof val == "object" || typeof val == "array") {
		        input.value = FB.JSON.stringify(val);
		    } else {
		    		input.value = val;
		    }
        form.appendChild(input);
      }
    });

    form.submit();
    form.parentNode.removeChild(form);
};

 

本来代码是:

postTarget: function(opts) {
    var form = document.createElement('form');
    form.action = opts.url;
    form.target = opts.target;
    form.method = 'POST';
    FB.Content.appendHidden(form);

    FB.Array.forEach(opts.params, function(val, key) {
      if (val !== null && val !== undefined) {
        var input = document.createElement('input');
        input.name = key;
        input.value = val;
        form.appendChild(input);
      }
    });

    form.submit();
    form.parentNode.removeChild(form);
}

 

facebook的fbml实际上是加载一个iframe,加载之前显示loading,facebook这里采用的是html5 的,facebook这里的实现偶尔会出现问题,一直loading,iframe显示不出来,facebook开发团队还没有给出解决方法,还是通过修 改js source解决

首先增加一个变量:

/********* fix fbjs api start:{set method used for FB.UIServer.iframe} *************/
FB.UIServer._SDialogMethod   = '';
/********* fix fbjs api end *************/

 修改FB.UIServer.prepareCall方法,增加以下代码,记录当前的ui method:

/********* fix fbjs api start:{set method used for FB.UIServer.iframe} *************/
  FB.UIServer._SDialogMethod = params.method.toLowerCase();
/********* fix fbjs api end *************/

 修改FB.UIServer.iframe方法,iframe加载的时候,直接显示:

 

/********* fix fbjs api start:{dialog loading bug,set default iframe and float div size} *************/
if ('stream.publish' == FB.UIServer._SDialogMethod) {
    var _SLoaderState    = false;	// -- 是否显示loading,这里改为false,不显示
    var _SVisibleState   = true;	// -- ui dialog是否可见,设为true,可见
    // -- set iframe background default size,only set width so it will show at center,if set height, the background can't resize if iframe size changed
    var _SInitSize  = { width: 575, height:'100%'};
    call.size.height    = 290;
} else if ('bookmark.add' == FB.UIServer._SDialogMethod) {
	var _SLoaderState    = false;
    var _SVisibleState   = true;
    // -- set iframe default size
    var _SInitSize  = { width: 460, height:'100%' };
} else if ('auth.permission' == FB.UIServer._SDialogMethod) {
    var _SLoaderState    = false;
    var _SVisibleState   = true;
    // -- set iframe default size
    if ('email' == call.params.ext_perm) {
  	var _SInitSize  = { width: 627, height:200};
      call.size.height    = 200;
    } else {
    	var _SInitSize  = { width: 627, height:350};
        call.size.height    = 350;
    }
} else {
    var _SLoaderState    = true;
    var _SVisibleState   = false;
    var _SInitSize  = false;
}
/********* fix fbjs api end *************/

 修改FB.Dialog.create方法,修改为以下,如果有初始大小的话,设置长宽值:

if (opts.visible) {
	  /********* fix fbjs api start:{dialog loading bug,set default iframe size} *************/
    try {
      if (opts._SInit) {
          dialog.style.width  = opts._SInit.width + 'px';
            dialog.style.height  = opts._SInit.height + 'px';
      }
    } catch (e) {}
    /********* fix fbjs api end *************/
    FB.Dialog.show(dialog);
}
 

这样修改之后,feed或者bookmark发布的时候,就不会一直卡在loading那里了,尤其是后台有大量数据加载时候,比较容易卡loading

最后修改授权时的弹出窗口问题,现在授权的时候,调用的是跟登录时候一样的接口,所以授权界面会在新窗口打开,这样就会被大部分浏览器屏蔽掉,在用户至上的现在,显然是不能接受的,所以参考旧api的方法,自定义一个ui method.

 

/************* fix fbjs api start: {permission dialog} ******************/
FB.provide('UIServer.Methods', {
  'auth.permission': {
    size      : { width: 627, height: 350 },
    url       : 'connect/prompt_permissions.php',
    transform : function(call) {
      //FIXME
      if (!FB._apiKey) {
        FB.log('FB.login() called before calling FB.init().');
        return;
      }

      // if we already have a session and permissions are not being requested,
      // we just fire the callback
      if (FB._session && !call.params.perms) {
        FB.log('FB.login() called when user is already connected.');
        call.cb && call.cb({ status: FB._userStatus, session: FB._session });
        return;
      }
      
      var
        xdHandler = FB.Auth.xdHandler,
        cb        = call.cb,
        id        = call.id,
        session   = FB._session,
        cancel    = xdHandler(
          cb,
          id,
          'parent',
          true, // isDefault
          FB._userStatus,
          session),
        next      = xdHandler(
          cb,
          id,
          'parent',
          false, // isDefault
          'connected',
          session);

      FB.copy(call.params, {
        cancel_url              : cancel,
        channel_url             : window.location.toString(),
        next                    : next,
        ext_perm                : call.params.perms
      });
      delete call.cb;
      delete call.params.perms; //TODO fix name to be the same on server
      return call;
    }
  }
});
/************* fix fbjs api end ******************/

 需要授权时,调用以下函数:

FB.ui(
   {
     method: 'auth.permission',
     perms: p_permissions
   },
   function(response){
      if ('' == response) {
          p_callback('failed');
          return false;
      }
      if (response.perms && egi.test(response.perms)) {
          // -- success
          var p_state = 'success';
      } else {
          var p_state = 'failed';
      }
      if (typeof p_callback == 'function') {
          p_callback(p_state);
      }
  }
);
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值