鉴于文件的URI,我想在新标签页(不是新窗口)中将其打开。
It looks like 无法使用$window.open(uri, '_blank')
。
所以,我尝试了以下技巧:
var link = angular.element('<a href="uri-here" target="_blank"></a>');
angular.element(document.body).append(link);
link[0].click();
link.remove();
和it works。
但是,如果我在promise回调中放置完全相同的代码,它就不再起作用了(它会在新窗口中打开文件)。
知道这里发生了什么吗?
答案 0 :(得分:11)
从您的代码/内容中,您无法强制浏览器打开新标签页(而不是新窗口,反之亦然)。这取决于浏览器设置,以某种方式强制它。
其他任何事都会带来安全风险。
答案 1 :(得分:4)
让我们了解弹出窗口阻止程序的工作原理。
如果用户触发该功能打开一个新的网址,那么弹出阻止程序将允许它(它应该应用于任何现代浏览器 - 至少是firefox,chrome)
如果不是来自用户(如后台的javascript函数,承诺或任何其他功能不是来自用户),浏览器将阻止,除非用户手动将站点列入白名单。
这不起作用。
function openInNewTab() {
window.open('http://stackoverflow.com','_blank');
}
openInNewTab();//fail
这是有效的
<h1><button onclick="openInNewTab()">Open In New Tab - working</button></h1>
我创建了简单的plunkr版本 - http://plnkr.co/edit/QqsEzMtG5oawZsQq0XBV?p=preview
所以,回答你的问题。除非用户授权它(用户触发它或白色列出该站点),否则是不可能的。
引自firefox -
弹出窗口或弹出窗口是自动显示的窗口 未经您许可。
https://support.mozilla.org/en-US/kb/pop-blocker-settings-exceptions-troubleshooting
*在新标签页/新窗口中打开没有任何区别。弹出窗口阻止程序仍将始终阻止。它并不意味着如果在新标签页中打开,浏览器将允许。对于某些浏览器默认以这种方式设置是巧合的。
解决方法强>
在后台执行后,您可以明确要求用户触发在新选项卡中打开的功能 您可以在UI中显示消息,要求用户打开该URL。 示例 - http://plnkr.co/edit/iyNzpg64DtsrijAGbHlT?p=preview
答案 2 :(得分:2)
您只能在用户触发的click
事件处理程序中打开新窗口。
原因是可用性。
我不确定所有浏览器是否都有此行为,但某些浏览器不允许脚本打开Windows 而不会引起用户注意。想象一下,当您访问网页时,网页会突然打开几个窗口=&gt;这很烦人。
请参阅此DEMO(使用我的Chrome和Firefox测试过),即使我们按脚本触发点击事件,浏览器仍会阻止弹出窗口。
$("#test").click(function(){
openInNewTab();
});
$("#test").click();
您无法在ajax成功回调中打开一个新窗口,因为您的ajax成功是在单击事件处理程序完成执行后的另一个循环中运行的。
有关解决方法的信息,请参阅此link
如果我在promise回调中输入完全相同的代码,它就不起作用 不再(它在新窗口中打开文件)。
我很惊讶您仍然可以打开一个新窗口。但是这个问题确实与用户触发的点击事件有很多关系。
答案 3 :(得分:1)
你的问题是双重的,两个折叠都在不确定的领域。
在过去的浏览器中,window.open
就是这样做了 - 打开一个新窗口。那是因为标签的概念尚未发明。当引入标签时,它们的处理方式与窗口完全相同,以提高兼容性,而这种传统一直持续到今天。那个以及window.open
仅为standardized very recently的事实意味着JavaScript无法区分窗口和标签。
没有“正常”的方式来指定链接是否应在新标签页中打开。但是可以使用以下hack:指定open
调用的自定义窗口大小(通过第三个参数),如下所示:
window.open('http://example.com', '', 'width=' + screen.width);
这会导致几乎所有浏览器都打开一个单独的窗口,因为标签不能有自定义大小。
在JavaScript中,有受信任的事件和不受信任的事件。例如,可信事件是用户对链接的合法点击,而不受信任的事件则是对链接的手动click()
调用。
只有受信任的事件处理程序才能打开新的窗口/标签。这是为了防止客户端攻击导致浏览器崩溃或通过在mouseover
或类似内容上快速打开一百个标签来混淆用户。
您的第二个示例不起作用,因为弹出窗口阻止程序会阻止您通过click()
触发的不受信任事件。虽然它是由真正的点击引起的,但是中间的异步调用会切断到可信度的链接。
答案 4 :(得分:0)
$http.get('https://api.github.com/users/angular').then(openInNewTab());
EDIT ----------------
不知道为什么但是从回调函数调用的click()方法与直接调用它的方式不同。
您可以在此处看到设置间隔示例。
这就是为什么我直接调用函数而不是通过回调。
答案 5 :(得分:0)
或者您可以使用$ window服务,请参阅此处:http://plnkr.co/edit/8egebfFj4T3LwM0Kd64s?p=preview
angular.module("Demo", []).controller("DemoCtrl", function($scope, $http, $window) {
$scope.uri = 'http://martinfowler.com/ieeeSoftware/whenType.pdf';
function openInNewTab() {
var link = angular.element('<a href="' + $scope.uri + '" target="_blank"></a>');
angular.element(document.body).append(link);
link[0].click();
link.remove();
}
$scope.works = openInNewTab;
$scope.doesntWork = function() {
$http.get('https://api.github.com/users/angular').then($window.open($scope.uri));
};
});
答案 6 :(得分:0)
简而言之:我们记得对新窗口的引用以及之后更改位置。