120 Stimmen

Wie man erkennt, wann die FB.init von Facebook abgeschlossen ist

Das alte JS SDK hatte eine Funktion namens FB.ensureInit. Das neue SDK scheint keine solche Funktion zu haben... wie kann ich sicherstellen, dass ich keine API-Aufrufe tätige, bis sie vollständig initiiert ist?

Ich füge dies oben auf jeder Seite ein:

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

141voto

serg Punkte 106383

Aktualisierung am 04. Jan. 2012

Es scheint, dass man nicht einfach FB-abhängige Methoden aufrufen kann (zum Beispiel FB.getAuthResponse() ) gleich nach FB.init() wie früher, als FB.init() scheint jetzt asynchron zu sein. Das Einbinden Ihres Codes in FB.getLoginStatus() Antwort scheint den Trick zu tun, um zu erkennen, wann die API vollständig bereit ist:

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

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

};  

oder bei Verwendung von fbEnsureInit() Umsetzung von unten:

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

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

};  

Ursprünglicher Beitrag:

Wenn Sie nur ein Skript ausführen wollen, wenn FB initialisiert wird, können Sie eine Callback-Funktion in 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
  };

Wenn Sie einen exakten Ersatz für FB.ensureInit wollen, müssen Sie selbst etwas schreiben, da es keinen offiziellen Ersatz gibt (großer Fehler imo). Hier ist, was ich verwende:

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

Verwendung:

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

39voto

shpoont Punkte 605

Facebook hat bereits einen Mechanismus zum Abonnieren von Authentifizierungsereignissen bereitgestellt.

In Ihrem Fall verwenden Sie " Status: wahr "Das bedeutet, dass das FB-Objekt Facebook nach dem Anmeldestatus des Benutzers fragt.

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

Durch den Aufruf von "FB.getLoginStatus()" führen Sie die gleiche Anfrage aus wieder .

Stattdessen könnten Sie verwenden FB.Event.subscribe zu abonnieren auth.statusChange ou auth.authResponseChange Veranstaltung BEVOR Sie rufen FB.init auf

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

Höchstwahrscheinlich, wenn Sie " Status: false " können Sie jeden Code direkt nach FB.init ausführen, da es keine asynchronen Aufrufe geben wird.

12voto

vladaman Punkte 3477

Hier ist eine Lösung für den Fall, dass Sie jquery und 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
};

11voto

user2253630 Punkte 111

Eine andere Möglichkeit zu prüfen, ob FB initialisiert wurde, ist die Verwendung des folgenden Codes:

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

So könnten Sie in Ihrem "page ready"-Ereignis ns.FBInitialized prüfen und das Ereignis auf eine spätere Phase verschieben, indem Sie setTimeOut verwenden.

5voto

Karl Rosaen Punkte 4280

Während einige der oben genannten Lösungen funktionieren, dachte ich, ich würde unsere letztendliche Lösung posten - die eine "ready"-Methode definiert, die ausgelöst wird, sobald FB initialisiert und einsatzbereit ist. Es hat den Vorteil gegenüber anderen Lösungen, dass es sicher ist, entweder vor oder nachdem FB bereit ist, aufzurufen.

Er kann folgendermaßen verwendet werden:

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

Hier ist die Quelldatei (beachten Sie, dass sie in einem Namensraum "f52.fb" definiert ist).

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

})();

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X