即使我刚刚使用它,FB仍未定义

时间:2011-10-12 23:13:46

标签: javascript jquery facebook facebook-javascript-sdk

我正在尝试将Facebook Like按钮添加到我正在创建的小部件中。我用来将Facebook喜欢按钮添加到我的页面的代码如下:

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

*在JavaScript中也存在changeView函数。

当我运行代码时,即使按钮已创建,我也会收到错误:Uncaught ReferenceError: FB is not defined。该错误指向包含FB.XFBML.parse代码的行。我的JavaScript需要做些什么吗?

3 个答案:

答案 0 :(得分:15)

window.fbAsyncInit开头的大脚本块的重点是Facebook SDK以异步方式加载

即使您在jQuery文档就绪回调中对FB进行了调用,但这还不足以确保在执行该代码时加载SDK。

幸运的是,完全存在window.fbAsyncInit目的:在SDK加载之前它不会运行。

来自Facebook's docs

  

分配给window.fbAsyncInit的功能在SDK完成后立即运行   已加载。加载SDK后要运行的任何代码   应该放在这个函数中并在调用FB.init之后。   例如,您可以在此处测试其登录状态   用户或订阅您的应用程序所在的任何Facebook活动   感兴趣。

答案 1 :(得分:15)

我遇到了这个问题并且解决了它与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比Chrome等Webkit浏览器更容忍。我无法弄清楚为什么我的jQuery没有在Chrome中正常工作......好吧,这就是原因。

我希望这有助于某人。

答案 2 :(得分: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
});

然后,您会在window.fbAsyncInit行之后$(window).triggerHandler('fbAsyncInit')致电FB.init()