古い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>
2012年1月4日に更新
FB.getAuthResponse()
は非同期のように見えるため、以前と同様にFB.init()
の直後にFB依存メソッド(たとえば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が初期化されているときにスクリプトを実行したい場合は、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
};
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();
}
}
}
使用法:
fbEnsureInit(function() {
console.log("this will be run once FB is initialized");
});
実際、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
});
「FB.getLoginStatus()」を呼び出すことで、同じリクエストを実行していますagain。
代わりに FB.Event.subscribe を使用してauth.statusChangeまたはにサブスクライブできますauth.authResponseChangeイベント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
});
おそらく、「status:false」を使用する場合、非同期呼び出しがないため、FB.initの直後に任意のコードを実行できます。
jquery および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
};
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 = (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
};
})();
これは、イベントもタイムアウトも必要としない、より簡単な方法です。ただし、jQueryが必要です。
jQuery.holdReady()
(docs) を使用します
したがって、jQueryスクリプトの直後に、readyイベントを遅延させます。
<!-- 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>
次に、Facebookの初期化関数でリリースします。
window.fbAsyncInit = function() {
FB.init({
appId: '11111111111111',
cookie: true,
xfbml: false,
version: 'v2.4'
});
// release the ready event to execute
$.holdReady( false );
};
その後、通常どおりreadyイベントを使用できます。
$(document).ready( myApp.init );
SetTimeoutまたはsetIntervalを使用する代わりに、遅延オブジェクトに固執します(jQuery here による実装)。 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();
});
編集注:次のヘルパースクリプトを更新し、使いやすく/簡単なクラスを作成しました。ここで確認してください::: https://github.com/tjmehta/fbExec.js
window.fbAsyncInit = function() {
FB.init({
//...
});
window.fbApiInit = true; //init flag
if(window.thisFunctionIsCalledAfterFbInit)
window.thisFunctionIsCalledAfterFbInit();
};
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.
}
});
});
}
(FB.loginは、FBの初期化後に実行する必要があります)
fbEnsureInit(function(){
FB.login(
//..enter code here
);
});
(FB.initとFBユーザーがログインする必要があります後に、FB.apiを実行する必要があります。)
fbEnsureInitAndLoginStatus(function(){
FB.api(
//..enter code here
);
});
イベントに登録できます:
すなわち)
FB.Event.subscribe('auth.login', function(response) {
FB.api('/me', function(response) {
alert(response.name);
});
});
小さいが重要な通知:
FB.getLoginStatus
はFB.init
の後に呼び出す必要があります。そうでない場合、イベントは発生しません。
FB.Event.subscribe('auth.statusChange', callback)
を使用できますが、ユーザーがFacebookにログインしていない場合は起動しません。
以下は両方の機能を備えた作業例です
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'));
Facebook APIはFB._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(FBreadyState);
Facebookのall.jsを読み込むためにasync = trueを使用していないことにも注意してください。これは、私の場合、UIへのサインインと機能の駆動をより確実に支援しているようです。
FbAsyncInitが機能しない場合があります。理由がわからないので、この回避策を使用します:
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);