Javascript 如何检测facebook';s FB.init已完成

Javascript 如何检测facebook';s FB.init已完成,javascript,facebook,jquery,Javascript,Facebook,Jquery,旧的JSSDK有一个名为FB.ensureInit的函数。新的SDK似乎没有这样的功能。。。如何确保在完全启动api之前不进行api调用 我在每一页的顶部都包含以下内容: <div id="fb-root"></div> <script> window.fbAsyncInit = function() { FB.init({ appId : '<?php echo $conf['fb']['appid']; ?>',

旧的JSSDK有一个名为FB.ensureInit的函数。新的SDK似乎没有这样的功能。。。如何确保在完全启动api之前不进行api调用

我在每一页的顶部都包含以下内容:

<div id="fb-root"></div>
<script>
  window.fbAsyncInit = function() {
    FB.init({
      appId  : '<?php echo $conf['fb']['appid']; ?>',
      status : true, // check login status
      cookie : true, // enable cookies to allow the server to access the session
      xfbml  : true  // parse XFBML
    });
    FB.Canvas.setAutoResize();
  };

  (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);
  }());
</script>

window.fbAsyninit=函数(){
FB.init({
appId:“”,
状态:true,//检查登录状态
cookie:true,//启用cookie以允许服务器访问会话
xfbml:true//解析xfbml
});
FB.Canvas.setAutoResize();
};
(功能(){
var e=document.createElement('script');
e、 src=document.location.protocol+'//connect.facebook.net/en_US/all.js';
e、 异步=真;
document.getElementById('fb-root').appendChild(e);
}());

2012年1月4日更新

似乎您不能像以前那样在
FB.init()
之后立即调用依赖于FB的方法(例如
FB.getAuthResponse()
),因为
FB.init()
现在似乎是异步的。将代码包装到
FB.getLoginStatus()
响应中似乎可以检测API何时完全就绪:

window.fbAsyncInit = function() {
    FB.init({
        //...
    });

    FB.getLoginStatus(function(response){
        runFbInitCriticalCode(); 
    });

};  
或者如果从下面使用
fbEnsureInit()
实现:

window.fbAsyncInit = function() {
    FB.init({
        //...
    });

    FB.getLoginStatus(function(response){
        fbApiInit = true;
    });

};  

原创帖子:

如果您只想在FB初始化时运行一些脚本,您可以在
FBasyninit
中放置一些回调函数:

  window.fbAsyncInit = function() {
    FB.init({
      appId  : '<?php echo $conf['fb']['appid']; ?>',
      status : true, // check login status
      cookie : true, // enable cookies to allow the server to access the session
      xfbml  : true  // parse XFBML
    });
    FB.Canvas.setAutoResize();

    runFbInitCriticalCode(); //function that contains FB init critical code
  };
我通过使用全局函数避免了使用setTimeout: 编辑说明:我已经更新了以下助手脚本,并创建了一个更易于使用的类;在这里查看:::

fbEnsureInit将在FB.init之后调用其回调

function fbEnsureInit(callback){
  if(!window.fbApiInit) {
    window.thisFunctionIsCalledAfterFbInit = callback; //find this in index.html
  }
  else{
    callback();
  }
}
fbEnsureInitAndLoginStatus将在FB.init和FB.getLoginStatus之后调用其回调

function fbEnsureInitAndLoginStatus(callback){
  runAfterFbInit(function(){
    FB.getLoginStatus(function(response){
      if (response.status === 'connected') {
        // the user is logged in and has authenticated your
        // app, and response.authResponse supplies
        // the user's ID, a valid access token, a signed
        // request, and the time the access token
        // and signed request each expire
        callback();

      } else if (response.status === 'not_authorized') {
        // the user is logged in to Facebook,
        // but has not authenticated your app

      } else {
        // the user isn't logged in to Facebook.

      }
    });
  });
}
FBIT示例用法: (FB.login需要在FB初始化后运行)

FBensureInputLogin示例用法: (FB.api需要在FB.init之后运行,FB用户必须登录。)


FacebookAPI监视FB.\u apiKey,因此在调用自己的API应用程序之前,您可以监视它,例如:

window.fbAsyncInit = function() {
  FB.init({
    //...your init object
  });
  function myUseOfFB(){
    //...your FB API calls
  };
  function FBreadyState(){
    if(FB._apiKey) return myUseOfFB();
    setTimeout(FBreadyState, 100); // adjust time as-desired
  };
  FBreadyState();
}; 
不确定这会有什么不同,但在我的例子中——因为我想确保UI已经准备好了——我已经用jQuery的document ready(上面最后一位)包装了初始化:


还请注意,我没有使用async=true加载Facebook的all.js,在我的情况下,这似乎有助于登录到UI并更可靠地驱动功能。

您可以订阅该事件:

(工业工程)


实际上,Facebook已经提供了一种订阅身份验证事件的机制

在您的情况下,您正在使用“状态:true”,这意味着FB对象将请求Facebook提供用户的登录状态

FB.init({
    appId  : '<?php echo $conf['fb']['appid']; ?>',
    status : true, // check login status
    cookie : true, // enable cookies to allow the server to access the session
    xfbml  : true  // parse XFBML
});
FB.init({
appId:“”,
状态:true,//检查登录状态
cookie:true,//启用cookie以允许服务器访问会话
xfbml:true//解析xfbml
});
通过调用“FB.getLoginStatus()”您再次运行相同的请求

相反,您可以在调用FB.init之前订阅auth.statusChangeauth.authResponseChange事件

FB.Event.subscribe('auth.statusChange', function(response) {
    if(response.status == 'connected') {
        runFbInitCriticalCode();
    }
});

FB.init({
    appId  : '<?php echo $conf['fb']['appid']; ?>',
    status : true, // check login status
    cookie : true, // enable cookies to allow the server to access the session
    xfbml  : true  // parse XFBML
});
FB.Event.subscribe('auth.statusChange',函数(响应){
如果(response.status==“已连接”){
runFbInitCriticalCode();
}
});
FB.init({
appId:“”,
状态:true,//检查登录状态
cookie:true,//启用cookie以允许服务器访问会话
xfbml:true//解析xfbml
});

最有可能的是,当使用“status:false”时,您可以在FB.init之后运行任何代码,因为不会有异步调用。

而不是使用任何setTimeout或setInterval,我将坚持使用延迟对象(由jQuery实现)。在适当的时候解析队列仍然很棘手,因为init没有回调,但将结果与事件订阅相结合(正如前面有人指出的那样),应该可以做到这一点,并且足够接近

伪代码段如下所示:

FB.Event.subscribe('auth.statusChange', function(response) {
   if (response.authResponse) {
       // user has auth'd your app and is logged into Facebook
   } else {
       // user has not auth'd your app, or is not logged into Facebook
   }
   DeferredObject.resolve();
});

如果您使用Facebook异步延迟加载,以下是一个解决方案:

//侦听事件
$(document).bind('fbInit',function(){
log('fbInit完成;FB对象可用');
});
//FB异步
window.fbAsyninit=函数(){
FB.init({appId:'app_id',
状态:正确,
曲奇:是的,
真的,
xfbml:true});
$(document.trigger('fbInit');//触发器事件
};

检查FB是否已初始化的另一种方法是使用以下代码:

ns.FBInitialized = function () {
    return typeof (FB) != 'undefined' && window.fbAsyncInit.hasRun;
};

因此,在页面就绪事件中,您可以检查ns.FBInitialized,并使用setTimeOut将事件推迟到稍后的阶段。

当上述一些解决方案起作用时,我想我会发布我们的最终解决方案-它定义了一个“就绪”方法,在FB初始化并准备就绪后立即触发。与其他解决方案相比,它的优点是在FB准备就绪之前或之后都可以安全地调用

它可以这样使用:

f52.fb.ready(function() {
    // safe to use FB here
});
这是源文件(请注意,它是在“f52.fb”命名空间中定义的)

if(typeof(f52)=='undefined'){f52={};}
f52.fb=(函数(){
var fbAppId=f52.inputs.base.fbAppId,
fbApiInit=false;
var WaitingReady=[];
var notifyQ=函数(){
var i=0,
l=等待就绪。长度;
对于(i=0;i  $(document).ready(FBreadyState);
FB.Event.subscribe('auth.login', function(response) {
  FB.api('/me', function(response) {
    alert(response.name);
  });
});
FB.init({
    appId  : '<?php echo $conf['fb']['appid']; ?>',
    status : true, // check login status
    cookie : true, // enable cookies to allow the server to access the session
    xfbml  : true  // parse XFBML
});
FB.Event.subscribe('auth.statusChange', function(response) {
    if(response.status == 'connected') {
        runFbInitCriticalCode();
    }
});

FB.init({
    appId  : '<?php echo $conf['fb']['appid']; ?>',
    status : true, // check login status
    cookie : true, // enable cookies to allow the server to access the session
    xfbml  : true  // parse XFBML
});
FB.Event.subscribe('auth.statusChange', function(response) {
   if (response.authResponse) {
       // user has auth'd your app and is logged into Facebook
   } else {
       // user has not auth'd your app, or is not logged into Facebook
   }
   DeferredObject.resolve();
});
ns.FBInitialized = function () {
    return typeof (FB) != 'undefined' && window.fbAsyncInit.hasRun;
};
f52.fb.ready(function() {
    // safe to use FB here
});
if (typeof(f52) === 'undefined') { f52 = {}; }
f52.fb = (function () {

    var fbAppId = f52.inputs.base.fbAppId,
        fbApiInit = false;

    var awaitingReady = [];

    var notifyQ = function() {
        var i = 0,
            l = awaitingReady.length;
        for(i = 0; i < l; i++) {
            awaitingReady[i]();
        }
    };

    var ready = function(cb) {
        if (fbApiInit) {
            cb();
        } else {
            awaitingReady.push(cb);
        }
    };

    window.fbAsyncInit = function() {
        FB.init({
            appId: fbAppId,
            xfbml: true,
            version: 'v2.0'
        });

        FB.getLoginStatus(function(response){
            fbApiInit = true;
            notifyQ();
        });
    };

    return {
        /**
         * Fires callback when FB is initialized and ready for api calls.
         */
        'ready': ready
    };

})();
 var interval = window.setInterval(function(){
    if(typeof FB != 'undefined'){
        FB.init({
            appId      : 'your ID',
            cookie     : true,  // enable cookies to allow the server to access// the session
            xfbml      : true,  // parse social plugins on this page
            version    : 'v2.3' // use version 2.3
        });

        FB.getLoginStatus(function(response) {
            statusChangeCallback(response);
        });
        clearInterval(interval);
    }
},100);
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
    $.holdReady( true ); // don't fire ready until told (ie when FB loaded)
</script>
window.fbAsyncInit = function() {
    FB.init({
        appId: '11111111111111',
        cookie: true,
        xfbml: false,
        version: 'v2.4'
    });

    // release the ready event to execute
    $.holdReady( false );
};
$(document).ready( myApp.init );
window.fbAsyncInit = function() {
    FB.Event.subscribe('auth.statusChange', function(response) {
        console.log( "FB.Event.subscribe auth.statusChange" );
        console.log( response );
    });

    FB.init({
        appId   : "YOUR APP KEY HERE",
        cookie  : true,  // enable cookies to allow the server to access
                // the session
        xfbml   : true,  // parse social plugins on this page
        version : 'v2.1', // use version 2.1
        status  : true
    });

    FB.getLoginStatus(function(response){
        console.log( "FB.getLoginStatus" );
        console.log( response );
    });

};

// Load the SDK asynchronously
(function(d, s, id) {
    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s); js.id = id;
    js.src = "//connect.facebook.net/en_US/sdk.js";
    fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));