Google+登录按钮并不总是加载

时间:2016-01-05 15:28:59

标签: javascript jquery angularjs google-plus

我的index.html底部有以下Javascript:

<script>
  function signInCallback(authResult) {
    if (authResult.code && authResult.access_token) {
      if (authResult['g-oauth-window']) {
        $.post('/auth/google/callback', {code: authResult.code, access_token: authResult.access_token}).done
          (function(data) {
            window.location.href = data.redir;
          });
      }
    }
  };

  (function() {
    $('#button-address').tooltip();
    var po = document.createElement('script');
    po.type = 'text/javascript';
    po.async = true;
    po.src = 'https://apis.google.com/js/client:plusone.js';
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(po, s);
  })();
</script>

...以及Angular指令模板中的HTML:

<div id="signinButton">
  <span
    class="g-signin"
    data-scope="email"
    data-clientid="CLIENTID.apps.googleusercontent.com"
    data-redirecturi="postmessage"
    data-accesstype="offline"
    data-cookiepolicy="single_host_origin"
    data-callback="signInCallback">
  </span>
</div>

此代码在我的Angular应用登录页面上呈现Google+登录按钮。问题是按钮不呈现的时间约为30%,用户需要刷新页面直到它出现。我相信这是因为有时在运行JS之前没有呈现#signinButton div。这听起来像是问题,如果是这样的话,我怎么能延迟JS运行直到#signinButton div被渲染以确保按钮总是出现?

3 个答案:

答案 0 :(得分:1)

由于它是AngularJS应用程序,为什么不使用像这样的指令:angular-directive.g-signin ? 这个例子非常明显。

答案 1 :(得分:1)

取决于document.ready或只是在页面末尾删除代码会设置潜在的竞争条件,因为无法保证您要将事件附加到的DOM节点存在(实际上它保证了它) 还不会存在;只有当注入的脚本的加载时间足够长才能在脚本到达时呈现它时,它才会起作用。)

假设client:plusone.js处的脚本在链接时希望看到现有的DOM节点#signinButton,您可以通过将该节点作为呈现#signinButton的指令的一部分来保证该节点的存在。 :

var app = angular.module("foo", []);
app.directive('signinButton', function($timeout) {
  return {
    template: '<div id="signinButton">...etc...</div>',
    link: function() {
      var s = document.getElementsByTagName("script")[0];
      var url = 'https://apis.google.com/js/client:plusone.js';
      if (s.src !== url) { /* Don't re-insert the script if it's already there */
        $timeout(function() { // force this to run in the next $digest, after the directive template is rendered
          var po = document.createElement('script');
          po.type = 'text/javascript';
          po.async = true;
          po.src = url;
          s.parentNode.insertBefore(po, s);
        });
      }
    }
  }
});

(回调函数可以像现在一样保留在文档的末尾,因为那显然是client:plusone.js期望找到它的地方,或者你可以从指令中将它附加到窗口对象。)< / p>

答案 2 :(得分:0)

将你的函数调用放在$(document).ready()中可能会解决你的问题吗?

$(document).ready(function(){
    $('#button-address').tooltip();
    var po = document.createElement('script');
    po.type = 'text/javascript';
    po.async = true;
    po.src = 'https://apis.google.com/js/client:plusone.js';
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(po, s);
})