如何检测facebook的FB.init何时完成

Pab*_*blo 114 javascript facebook

旧的JS SDK有一个名为FB.ensureInit的函数.新的SDK似乎没有这样的功能......我怎样才能确保在完全启动之前我不进行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>
Run Code Online (Sandbox Code Playgroud)

ser*_*erg 138

2012年1月4日更新

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

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

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

};  
Run Code Online (Sandbox Code Playgroud)

或者如果使用fbEnsureInit()以下实现:

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

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

};  
Run Code Online (Sandbox Code Playgroud)

原帖:

如果你想在初始化FB时运行一些脚本,你可以在里面放一些回调函数fbAsyncInit:

  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
  };
Run Code Online (Sandbox Code Playgroud)

如果你想要完全替换FB.ensureInit那么你必须自己写一些东西,因为没有官方替代品(大错误imo).这是我使用的:

  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();

    fbApiInit = true; //init flag
  };

  function fbEnsureInit(callback) {
        if(!window.fbApiInit) {
            setTimeout(function() {fbEnsureInit(callback);}, 50);
        } else {
            if(callback) {
                callback();
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

用法:

fbEnsureInit(function() {
    console.log("this will be run once FB is initialized");
});
Run Code Online (Sandbox Code Playgroud)

  • 调用FB.init后,我无法立即运行Facebook API请求 - 也许是因为我使用的方法是'fql.query'?不管怎样,我必须在fbApiInit标志上设置一个冗长的超时. (3认同)
  • 谢谢Serg ..你是个传奇! (2认同)

shp*_*ont 36

实际上Facebook已经提供了一种订阅认证事件的机制.

在您的情况下,您使用" status: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
});
Run Code Online (Sandbox Code Playgroud)

通过调用"FB.getLoginStatus()",您再次运行相同的请求.

相反,您可以使用FB.Event.subscribe 调用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
});
Run Code Online (Sandbox Code Playgroud)

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


vla*_*man 12

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

// listen to an Event
$(document).bind('fbInit',function(){
    console.log('fbInit complete; FB Object is Available');
});

// FB Async
window.fbAsyncInit = function() {
    FB.init({appId: 'app_id', 
         status: true, 
         cookie: true,
         oauth:true,
         xfbml: true});

    $(document).trigger('fbInit'); // trigger event
};
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢它!唯一的问题是Facebook坚持你应该在开始<body>标签之后直接包含你的FB初始化代码,最佳实践说你应该在结束<body>标签之前加载jQuery.卫生署!鸡肉和鸡蛋.我很想说"搞砸你,Facebook"并在jQuery之后加载FB. (3认同)

小智 10

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

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

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


Kar*_*aen 5

虽然上面的一些解决方案有效,但我认为我会发布最终的解决方案 - 它定义了一个'就绪'方法,一旦FB初始化并准备好就会触发.它具有优于其他解决方案的优势,可以在FB准备就绪之前或之后调用.

它可以像这样使用:

f52.fb.ready(function() {
    // safe to use FB here
});
Run Code Online (Sandbox Code Playgroud)

这是源文件(请注意,它是在'f52.fb'命名空间中定义的).

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
    };

})();
Run Code Online (Sandbox Code Playgroud)