我正在尝试在AngularJS应用程序中使用Github API的web auth flow。当我的注册表单提交时,我想打开一个新窗口将它们发送到auth页面。通常我会在用户事件中使用window.open
以确保它不会被弹出窗口阻止程序捕获。
在我的角度应用程序中,我正在包装一些Github api和Angular服务,打开窗口的代码就在那里。因为它被阻止了。我还尝试将它放在控制器中的一个函数中,该函数由表单通过ng-submit
调用。
所以问题是,是否有一种优雅的方式在我的服务或控制器内的某个地方提交表单上打开新页面,或者我是否需要找到另一种方法来执行此操作?
答案 0 :(得分:20)
默认情况下,Chrome会阻止不是用户直接操作的弹出窗口。在你的情况下,我假设,对window.open的调用是在回调函数中进行的。这使它成为异步,Chrome会阻止它。
//before
$scope.userClicked = function(){
$http.post('your/api/endpoint',{data:x}).then(function(r){
$window.open(r.data.url,'window name','width=800,height=600,menubar=0,toolbar=0');
});
}
然而,有一种解决方法可以使这项工作。在回调函数之外实例化您的窗口,您可以引用该变量来更改回调函数中该窗口的目标URL。
//after
$scope.userClicked = function(){
var popup = $window.open('','window name','width=800,height=600,menubar=0,toolbar=0');
popup.document.write('loading ...');
$http.post('your/api/endpoint',{data:x}).then(function(r){
popup.location.href = r.data.url;
});
}
答案 1 :(得分:4)
你无法摆脱脚本化自动化window.open的弹出窗口拦截器。只有真实用户的号召性用语才会打开一个新窗口,而不会被弹出窗口拦截器阻止。想象一下,在浏览器中没有弹出窗口阻止程序的网站中,javascript会在循环中打开100个弹出窗口。你想要吗?它过去常常出现在像病毒这样的旧时代,但现代浏览器非常聪明,这种烦恼得到了优雅的处理。
答案 2 :(得分:2)
你可以简单地在click
事件内容中创建一个指令来执行此操作:
yourapp.directive('awesomeClick', ['$parse',function ($parse): ng.IDirective {
return {
restrict: 'A',
link: (scope, element:JQuery, attrs) => {
var fn = $parse(attrs.awesomeClick);
element.on('click', function (event) {
// open the window if you want here
scope.$apply(function () {
fn(scope, { $event: event });
});
});
}
}
}]);