Javascript FB 未定义,即使我刚刚使用它
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7747668/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
FB is undefined even though I just used it
提问by Dave Long
I am trying to add a Facebook Like button to a widget that I am creating. The code that I use to add the Facebook like button to my page is as follows:
我正在尝试将 Facebook Like 按钮添加到我正在创建的小部件中。我用来将 Facebook 点赞按钮添加到我的页面的代码如下:
widget.html
小部件.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
小部件.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);
});
*The changeView function does exist as well in the JavaScript.
*在 JavaScript 中也确实存在 changeView 函数。
When I run the code, I get an error: Uncaught ReferenceError: FB is not defined
even though the button is created. The error is pointing to the line containing FB.XFBML.parse code. Is there something I need to do differently in my JavaScript?
运行代码时,出现错误:Uncaught ReferenceError: FB is not defined
即使按钮已创建。错误指向包含 FB.XFBML.parse 代码的行。我需要在 JavaScript 中做一些不同的事情吗?
回答by Brandon
I had this problem and solved it similarly to the solution that Amry provided so I'm posting it here in case someone else needs to use it.
我遇到了这个问题,并以类似于 Amry 提供的解决方案解决了它,所以我将它发布在这里以防其他人需要使用它。
I made the initial assumption that the FB initialization call made in the fbAsyncInit method would initialize immediately, so I too coded my use of the FB object in a $(document).ready()
method. That is not the case. fbAsyncInit takes quite some time after the page loads to finish initializing. Here is my solution, when using jQuery on my site:
我最初假设在 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>
The last task is to simply switch your $(document).ready()
code to a bind for your event. This goes where ever you are using the FB object.
最后一个任务是简单地将您的$(document).ready()
代码切换到您的事件的绑定。这适用于您使用 FB 对象的任何地方。
(function($) {
$(document).bind('FBSDKLoaded', function() {
//Code using the FB object goes here.
});
})(jQuery);
One thing I should also mention: Firefox is a lot more tolerant of this than Webkit browsers like Chrome. I couldn't figure out why NONE of my jQuery was working properly in Chrome... well, this was why.
我还应该提到的一件事是:与 Chrome 等 Webkit 浏览器相比,Firefox 对此的容忍度要高得多。我不明白为什么我的 jQuery 没有一个在 Chrome 中正常工作......好吧,这就是原因。
I hope this helps someone.
我希望这可以帮助别人。
回答by John Flatness
The whole point of that big script block starting with window.fbAsyncInit
is that the Facebook SDK gets loaded asynchronously.
这个大脚本块的重点window.fbAsyncInit
是 Facebook SDK 被异步加载。
Even though you've got your calls against FB
inside a jQuery document ready callback, that isn't sufficient to ensure the SDK is loaded when that code is executed.
即使您在FB
jQuery 文档就绪回调中进行了调用,这也不足以确保在执行该代码时加载 SDK。
Fortunately, window.fbAsyncInit
exists for exactlythat purpose: it won't be run until the SDK has loaded.
幸运的是,它的window.fbAsyncInit
存在正是为了这个目的:在 SDK 加载之前它不会运行。
From Facebook's docs:
来自Facebook 的文档:
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.
分配给的函数会
window.fbAsyncInit
在 SDK 加载后立即运行。您希望在 SDK 加载后运行的任何代码都应放置在此函数中以及调用 FB.init 之后。例如,您可以在此处测试用户的登录状态或订阅您的应用程序感兴趣的任何 Facebook 事件。
回答by Amry
FB was not yet defined at that point of time. You haven't used it yet, you had simply typed it earlier up. The FB.XFMBL.parse
line will execute when the document is ready. Same goes to the //connect.facebook.net/en_US/all.js
line. So it's not really reliable which code will execute first if it is executed from the same event.
当时还没有定义 FB。你还没有使用它,你只是早些时候输入了它。该FB.XFMBL.parse
行将在文档准备好时执行。同去的//connect.facebook.net/en_US/all.js
路线。因此,如果从同一事件中执行哪个代码将首先执行,则它并不可靠。
What you can do is somehow have the code you want be executed from window.fbAsyncInit
. From that point onwards, you can be sure that FB
is ready to be used.
您可以做的是以某种方式让您想要从window.fbAsyncInit
. 从那时起,您可以确定它FB
已准备好使用。
One way you can do if you don't want to mix the code you have in widget.js is by using jQuery's custom event. So instead of having $(function() { ... });
, you will have something along this line:
如果您不想混合widget.js 中的代码,您可以采用的一种方法是使用jQuery 的自定义事件。因此$(function() { ... });
,您将拥有以下内容,而不是拥有 :
$(window).bind('fbAsyncInit', function() {
// Your code here
});
Then you will have window.fbAsyncInit
call $(window).triggerHandler('fbAsyncInit')
just after the FB.init()
line.
然后你会在线路后window.fbAsyncInit
打电话。$(window).triggerHandler('fbAsyncInit')
FB.init()