Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 谷歌+;登录按钮并不总是加载_Javascript_Jquery_Angularjs_Google Plus - Fatal编程技术网

Javascript 谷歌+;登录按钮并不总是加载

Javascript 谷歌+;登录按钮并不总是加载,javascript,jquery,angularjs,google-plus,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.cod

我在
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>

函数signInCallback(authResult){
if(authResult.code&&authResult.access\u令牌){
if(authResult['g-oauth-window']){
$.post('/auth/google/callback',{code:authResult.code,access_-token:authResult.access_-token})。完成
(功能(数据){
window.location.href=data.redir;
});
}
}
};
(功能(){
$(“#按钮地址”)。工具提示();
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(“脚本”)[0];
s、 parentNode.insertBefore(po,s);
})();
…以及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以确保按钮始终出现?

既然它是AngularJS应用程序,为什么不使用像这样的指令: ?
这个例子非常简单。

将函数调用放在
$(文档)中。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);
})

您需要修改此项以在Angular的生命周期内工作:
document.ready
是Angular开始设置DOM时,而不是完成DOM时。取决于
document.ready
或只是在页面末尾插入代码会设置潜在的竞争条件,因为无法保证要附加事件的DOM节点是否存在(只有当注入脚本的加载时间足够长,Angular才能在脚本到达时完成渲染时,它才会工作。这意味着除了第一次非缓存访问外,任何其他访问都不能工作。)

假设
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);
        });
      }
    }
  }
});
var-app=angular.module(“foo”,[]);
应用指令('signinButton',函数($timeout){
返回{
模板:“…等…”,
链接:函数(){
var s=document.getElementsByTagName(“脚本”)[0];
var url='1〕https://apis.google.com/js/client:plusone.js';
如果(s.src!==url){/*如果脚本已经存在,请不要重新插入它*/
$timeout(function(){//在呈现指令模板后,强制在下一个$digest中运行此命令
var po=document.createElement('script');
po.type='text/javascript';
po.async=true;
po.src=url;
s、 parentNode.insertBefore(po,s);
});
}
}
}
});

(回调函数对时间不敏感;它可以像现在一样停留在文档的末尾,因为这显然是
client:plusone.js
希望找到它的地方,或者您也可以从指令中将它附加到窗口对象。)

maby手动调用gapi.signn2.render('signinButton',options)在html之后,脚本在正文右下角?@Sebastian,是的yes@Sebastian,添加了详细信息,指出脚本块的位置,并指出my HTML位于Angular指令的模板内。Angular应用程序中的直接DOM操作是在玩火,因为您不在
$digest
循环。将此功能放在绘制
#signinButton
的指令中,而不只是在页面末尾转储它。此代码块已经位于我的
index.html
的最底部,我相信它完成了与
$(文档)相同的任务。就绪