繁体   English   中英

AngularJS:如何在新标签中打开文件?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM