2011-10-12 113 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 –

相关问题