114 votes

Comment détecter si le FB.init de Facebook est terminé ?

L'ancien SDK JS avait une fonction appelée FB.ensureInit. Le nouveau SDK ne semble pas disposer d'une telle fonction... comment puis-je m'assurer que je n'effectue pas d'appels à l'api avant qu'elle ne soit entièrement lancée ?

Je l'indique en haut de chaque page :

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

139voto

serg Points 43893

Mise à jour le 04 janvier 2012

Il semble que vous ne puissiez pas simplement appeler des méthodes dépendantes de FB (par exemple FB.getAuthResponse() ) juste après FB.init() comme avant, comme FB.init() semble être asynchrone maintenant. Enrouler votre code dans FB.getLoginStatus() semble faire l'affaire pour détecter quand l'API est entièrement prête :

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

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

};  

ou si vous utilisez fbEnsureInit() la mise en œuvre par le bas :

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

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

};  

Poste original :

Si vous voulez simplement exécuter un script lorsque FB est initialisé, vous pouvez mettre une fonction de rappel à l'intérieur. 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
  };

Si vous voulez un remplacement exact de FB.ensureInit, vous devrez écrire quelque chose vous-même car il n'y a pas de remplacement officiel (grosse erreur imo). Voici ce que j'utilise :

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

Utilisation :

fbEnsureInit(function() {
    console.log("this will be run once FB is initialized");
});

36voto

shpoont Points 405

En fait, Facebook a déjà fourni un mécanisme permettant de s'abonner aux événements d'authentification.

Dans votre cas, vous utilisez " statut : vrai "Ce qui signifie que l'objet FB demandera à Facebook le statut de connexion de l'utilisateur.

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

En appelant "FB.getLoginStatus()", vous exécutez la même requête. à nouveau .

Au lieu de cela, vous pouvez utiliser FB.Event.subscribe pour s'abonner à auth.statusChange o auth.authResponseChange événement AVANT vous appelez FB.init

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

Le plus souvent, lorsque vous utilisez " statut : faux "vous pouvez exécuter n'importe quel code juste après FB.init, car il n'y aura pas d'appels asynchrones.

12voto

vladaman Points 1506

Voici une solution au cas où vous utilisez jquery et Facebook Asynchronous Lazy Loading :

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

10voto

user2253630 Points 11

Une autre façon de vérifier si FB a été initialisé est d'utiliser le code suivant :

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

Ainsi, dans votre événement de page prête, vous pouvez vérifier ns.FBInitialized et reporter l'événement à une phase ultérieure en utilisant setTimeOut.

5voto

Karl Rosaen Points 2096

Bien que certaines des solutions ci-dessus fonctionnent, j'ai pensé poster notre solution finale - qui définit une méthode "ready" qui se déclenchera dès que FB sera initialisé et prêt à fonctionner. Elle a l'avantage, par rapport aux autres solutions, de pouvoir être appelée en toute sécurité avant ou après que FB soit prêt.

Il peut être utilisé comme suit :

f52.fb.ready(function() {
    // safe to use FB here
});

Voici le fichier source (notez qu'il est défini dans un espace de nom '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
    };

})();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X