2011-10-12 112 views
9

我正在嘗試向我創建的窗口小部件添加一個Facebook Like按鈕。我用像按鈕添加Facebook到我的網頁的代碼如下:即使我剛剛使用它,FB也是未定義的

widget.html

<body> 
<div id="fb-root"></div> 
<script> 
    window.fbAsyncInit = function() { 
     FB.init({ 
      appId : '263071593731910', 
      status : false, // check login status 
      cookie : true, // enable cookies to allow the server to access the session 
      xfbml : true // parse XFBML 
     }); 
    }; 
    (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> 
<div id="fb-button"></div> 
<script type="text/javascript" src="widget.js"></script> 

widget.js

$(function(){ 
var fb = $(document.createElement("fb:like")); 
fb.attr({ 
    href: data.facebook, 
    send: false, 
    layout: 'button_count', 
    width: 70, 
    'show_faces': false 
}); 
$("#fb-button").empty().append(fb); 
FB.XFBML.parse($("#fb-button").get(0)); 
FB.Event.subscribe('edge.create',changeView); 
}); 

*的changeView功能確實存在,以及在JavaScript中。

當我運行代碼時,即使創建按鈕,我也會收到錯誤:Uncaught ReferenceError: FB is not defined。該錯誤指向包含FB.XFBML.parse代碼的行。有什麼我需要在JavaScript中做不同的事情嗎?

+0

嘗試使用window.FB或document.FB –

回答

14

window.fbAsyncInit開始的那個大腳本塊的整個點是Facebook SDK以異步方式加載

儘管您在jQuery文檔就緒回調中針對FB調用了該函數,但這並不足以確保在該代碼執行時加載SDK。

幸運的是,window.fbAsyncInit對於確實存在那個目的:在SDK加載之前它不會運行。

Facebook's docs

The function assigned to window.fbAsyncInit is run as soon as the SDK is loaded. Any code that you want to run after the SDK is loaded should be placed within this function and after the call to FB.init. For example, this is where you would test the logged in status of the user or subscribe to any Facebook events in which your application is interested.

+2

好的。那麼有沒有像window.fbSyncInit這樣做會同步?或者在文檔的其他部分加載時運行的事件?我不確定如何將$(document).ready()與fb init結合起來,我知道所有的HTML元素都在那裏。 –

5

FB未在該時間點還沒有確定。你還沒有使用它,你只是簡單地輸入它。文檔準備好後,FB.XFMBL.parse行將執行。 //connect.facebook.net/en_US/all.js一致。因此,如果從同一個事件執行代碼,那麼首先執行哪個代碼並不可靠。

你可以做的是以某種方式讓你想要從window.fbAsyncInit執行的代碼。從那時起,你可以確定FB已準備好使用。

如果你不想混合你在widget.js中的代碼,你可以做的一種方法是使用jQuery的自定義事件。因此不是$(function() { ... });,你將有一些沿着這條線:

$(window).bind('fbAsyncInit', function() { 
    // Your code here 
}); 

然後,你將只是FB.init()行後有window.fbAsyncInit呼叫$(window).triggerHandler('fbAsyncInit')

13

我有這個問題,並解決它類似於解決方案,由Amry提供,所以我張貼在這裏,以防其他人需要使用它。

我做了一個初始假設,即fbAsyncInit方法中的FB初始化調用會立即初始化,所以我也編寫了在$(document).ready()方法中使用FB對象的代碼。事實並非如此。在加載頁面完成初始化之後,fbAsyncInit需要相當長的時間。這裏是我的解決方案,我的網站上使用jQuery時:

<script type="text/javascript"> 

    window.fbAsyncInit = function() { 

    FB.init({ 
     appId  : 'your_app_id', // App ID 
     channelUrl : 'your channel', 
     status  : true, // check login status 
     cookie  : true, // enable cookies to allow the server to access the session 
     xfbml  : true // parse XFBML 
    }); 
    jQuery(document).trigger('FBSDKLoaded'); //This is the most important line to solving the issue 
    }; 

    // Load the SDK Asynchronously 
    (function(d){ 
    var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0]; 
    if (d.getElementById(id)) {return;} 
    js = d.createElement('script'); js.id = id; js.async = true; 
    js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=269187653191150"; 
    ref.parentNode.insertBefore(js, ref); 
    }(document)); 

</script> 

的最後一個任務是簡單的$(document).ready()碼開關來爲您的活動綁定。這就是你使用FB對象的地方。

(function($) { 
    $(document).bind('FBSDKLoaded', function() { 
     //Code using the FB object goes here. 
    }); 

})(jQuery); 

我還應該提到的一件事:Firefox比Webkit瀏覽器(比如Chrome)更容忍這一點。我無法弄清楚爲什麼我的jQuery中沒有一個在Chrome中正常工作......呃,這就是爲什麼。

我希望這可以幫助別人。

+0

我愛你的男人! –

+0

很高興幫助某人! – Brandon

+0

布蘭登的回答是現貨和工作。不過,也有使用jQuery和FB與getScript()建議實現的說明:https://developers.facebook.com/docs/javascript/howto/jquery/v2.5 –

相關問題