有没有办法检测Facebook Javascript SDK是否成功加载?

Cha*_*eus 30 javascript sdk facebook

我使用Facebook作为我网站的会员制.它使用代码生成登录控件,允许用户通过他们的Facebook帐户登录.如果它们已经是成员,则基本上是一次点击,如果不是,则基本上是2(用于授予权限).

我遇到了一个问题...反馈表明登录按钮并不总是正确加载.它不是加载facebook登录控件,而是简单地说明(在文本中)"通过facebook登录" - 如果控件成功加载,这就是登录按钮会说的.

测试显示,当facebook javascript SDK无法完全加载(无论出于何种原因)时会发生什么.我见过url中的#阻止SDK加载的实例.

为了更好地支持这个问题,我将如何检测facebook javascript SDK是否已加载并准备就绪?这样,如果它失败了,我可以为用户留下某种注意事项.

以下是它当前添加到页面的方式:

<script>
window.fbAsyncInit = function () {
FB.init({
  appId: '***************',
  status: true,
  cookie: true,
  xfbml: true
});
FB.Event.subscribe('auth.login', function (response) {
  window.location.reload();
});

};
(function () {
  var e = document.createElement('script'); e.async = true;
  e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
  document.getElementById('fb-root').appendChild(e);
} ());

</script>
Run Code Online (Sandbox Code Playgroud)

ifa*_*our 47

您应该异步加载Javascript库并将所有与FB相关的函数放在window.fbAsyncInit方法中:

<div id="fb-root"></div>
<script>
  window.fbAsyncInit = function() {
    FB.init({
      appId      : 'YOUR_APP_ID', // App ID
      channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File
      status     : true, // check login status
      cookie     : true, // enable cookies to allow the server to access the session
      xfbml      : true  // parse XFBML
    });

    // Additional initialization code here
  };

  // 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";
     ref.parentNode.insertBefore(js, ref);
   }(document));
</script>
Run Code Online (Sandbox Code Playgroud)

此代码异步加载SDK,因此不会阻止加载页面的其他元素.这对于确保用户和SEO机器人的快速页面加载尤为重要.

上述代码中的URL是协议相对的.这使浏览器可以通过与包含页面相同的协议(HTTP或HTTPS)加载SDK,这将阻止"不安全内容"警告.

分配给的函数window.fbAsyncInit在加载SDK后立即运行.加载SDK后要运行的任何代码都应放在此函数中,并在调用之后FB.init.例如,您可以在此处测试用户的登录状态订阅您的应用程序感兴趣的任何Facebook事件.

一个简单的例子如下:

<div id="fb-root"></div>
<script>
  var isLoaded = false;
  window.fbAsyncInit = function() {
    FB.init({
      appId      : 'YOUR_APP_ID', // App ID
      channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File
      status     : true, // check login status
      cookie     : true, // enable cookies to allow the server to access the session
      xfbml      : true  // parse XFBML
    });
    isLoaded = true;

    // Additional initialization code here
  };

  function checkIfLoaded() {
    if(isLoaded) console.log("LOADED!");
    else console.log("NOT YET!");

    return false;
  }

  // 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";
     ref.parentNode.insertBefore(js, ref);
   }(document));
</script>
<a href="#" onclick="checkIfLoaded();">Check</a>
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述
(只需点击check链接几次)


请注意,您仍然可以构建Login Link服务器端和WITHOUT JavaScript.使用PHP-SDK的示例:

$loginUrl = $facebook->getLoginUrl();
...
...
<a href="<?php echo $loginUrl; ?>">
    <img src="http://static.ak.fbcdn.net/rsrc.php/zB6N8/hash/4li2k73z.gif">
</a>
Run Code Online (Sandbox Code Playgroud)


Leo*_*sky 8

加载SDK时触发事件:

window.fbAsyncInit = function() {
  FB.init({appId: "#{KeyManager.facebook_app_id}", status: true, cookie: true, xfbml: true});
  jQuery('#fb-root').trigger('facebook:init');
};
Run Code Online (Sandbox Code Playgroud)

并听取这样的事件:

$("#fb-root").bind("facebook:init", function() {
  ..
});
Run Code Online (Sandbox Code Playgroud)


Sim*_*ver 5

如果您正在使用 jQuery(并且您在 FB 初始化之前加载了 jQuery),您可以使用 Deferred 来运行额外的初始化。

<script>
    window.fbLoaded = $.Deferred();

    window.fbAsyncInit = function() {

        FB.init({
            appId      : '----------',
            xfbml      : true,
            status     : true,
            version    : 'v2.7'
        });

        window.fbLoaded.resolve();
    };


    (function(d, s, id){
        var js, fjs = d.getElementsByTagName(s)[0];
        if (d.getElementById(id)) {return;}
        js = d.createElement(s); js.id = id;
        js.src = "//connect.facebook.net/en_US/sdk.js";
        fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));

</script>
Run Code Online (Sandbox Code Playgroud)

然后在其他地方(在 JS 文件中)你可以这样做(实际上这个方法的关键是你可以把它放在你想要的任何地方,它们都会被触发):

 window.fbLoaded.done(function () { alert('FB initialized'); });
Run Code Online (Sandbox Code Playgroud)

注意:如果在添加done事件之前初始化完成,它将立即触发(这就是延迟的工作方式)。所以你可以把它放在任何你想要的地方。

如果 API 从未初始化,请务必测试您想要的行为(只需注释掉 (function(d,s,id)... part