[英]AngularJS: How to open a file in a new tab?
给定文件的URI,我想在新的选项卡 (而不是新窗口)中打开它。
看起来 不可能使用$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();
它的工作原理 。
但是,如果我在promise回调中放置完全相同的代码,它就不再起作用了(它在新窗口中打开文件)。
知道这里发生了什么吗?
从您的代码/内容中,您无法强制浏览器打开新选项卡(而不是新窗口,反之亦然)。 由浏览器设置决定以某种方式强制它。
任何其他东西都是安全风险。
让我们了解弹出窗口阻止程序的工作原理。
如果用户触发该功能打开一个新的网址,那么弹出阻止程序将允许它(它应该应用于任何现代浏览器 - 至少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
您只能在用户触发的 click
事件处理程序中打开新窗口。
原因是可用性 。
我不确定是否所有浏览器都有这种行为,但有些浏览器不允许脚本在没有用户注意的情况下打开窗口。 想象一下,当你访问一个网页时,突然,网页打开几个窗口=>这很烦人。
看到这个DEMO (用我的Chrome和Firefox测试过),即使我们通过脚本触发点击事件,浏览器仍会阻止弹出窗口。
$("#test").click(function(){
openInNewTab();
});
$("#test").click();
你无法在ajax成功回调中打开一个新窗口,因为你的ajax成功是在click事件处理程序完成执行后的另一个循环中运行的。
请参阅此链接以获取解决方法
如果我在promise回调中放置完全相同的代码,它就不再起作用了(它在新窗口中打开文件)。
我很惊讶您仍然可以打开一个新窗口。 但是这个问题确实与用户触发的点击事件有很多关系。
你的问题是双重的,两个折叠都在不确定的领域。
在过去的浏览器中, window.open
就是这样 - 打开一个新窗口。 那是因为标签的概念尚未发明。 当引入标签时,它们的处理方式与窗口完全相同,以提高兼容性,而这种传统一直持续到今天。 而且, window.open
最近才标准化 ,这意味着JavaScript无法区分窗口和标签。
没有“正常”方式来指定链接是否应在新选项卡中打开 。 但是,您可以使用以下hack:为open
调用指定自定义窗口大小(通过第三个参数),如下所示:
window.open('http://example.com', '', 'width=' + screen.width);
这将导致几乎所有浏览器都打开一个单独的窗口,因为标签不能具有自定义大小。
在JavaScript中,存在受信任事件和不受信任事件。 例如,可信事件是用户对链接的合法点击,而不受信任的事件是对链接的手动click()
调用。
只有受信任的事件处理程序才能打开新窗口/选项卡。 这是为了防止客户端攻击导致浏览器崩溃或通过在mouseover
或类似情况下快速打开一百个选项卡来混淆用户。
您的第二个示例不起作用,因为弹出窗口阻止程序会阻止您通过click()
触发的不受信任事件。 虽然它是由真正的点击引起的,但是中间的异步调用会切断到可信度的链接。
$http.get('https://api.github.com/users/angular').then(openInNewTab());
编辑 - - - - - - - -
不知道为什么但是从回调函数调用的click()方法与直接调用它的方式不同。
您可以在此处使用设置间隔示例查看它。
这就是为什么我直接调用函数而不是通过回调。
或者你可以使用$ 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));
};
});
对我们来说,以下方面运作良好: http : //blog-it.hypoport.de/2014/08/19/how-to-open-async-calls-in-a-new-tab-instead-of-new-window -within-AN-angularjs应用内/
简而言之:我们记得对新窗口的引用并在之后更改位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.