虽然我刚用过FB,但它没有定义

FB is undefined even though I just used it

本文关键字:定义 FB      更新时间:2023-09-26

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

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 . xfxml .parse代码的行。我需要在JavaScript中做一些不同的事情吗?

我有这个问题,并解决了类似的解决方案,Amry提供,所以我把它张贴在这里,以防有人需要使用它。

我最初假设在fbAsyncInit方法中进行的FB初始化调用将立即初始化,因此我也将FB对象的使用编码在$(document).ready()方法中。事实并非如此。在页面加载完成初始化后,需要相当长的一段时间。这是我的解决方案,当使用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中正常工作…这就是为什么。

window.fbAsyncInit开始的大脚本块的全部要点是Facebook SDK被异步加载

尽管你已经在jQuery文档准备好的回调中调用了FB,但这还不足以确保在执行代码时加载SDK。

幸运的是,window.fbAsyncInit的存在正是为了这个目的:它不会运行,直到SDK被加载。

来自Facebook的文档:

分配给window.fbAsyncInit的函数在SDK完成后立即运行加载。加载SDK后想要运行的任何代码应该放在这个函数中,并且在调用FB.init之后。例如,您将在这里测试控件的登录状态用户或订阅您的应用程序所在的任何Facebook事件感兴趣。

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()行之后。