我的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被渲染以确保按钮总是出现?
答案 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);
})