记录生活中的点滴,分享、学习、创新
打开新窗口的方式主要有 window.open, a标签增加target="_blank"属性,form标签增加target="_blank"属性
用户直接点击的事件是不会被浏览器拦截的,如DOM里面的form标签和a标签,用户点击可以正常打开新窗口。
<a href="https://www.baidu.com" target="_blank">百度</a>
<form action="https://www.baidu.com" target="_blank">
<input type="hidden" name="key" value="value">
<button type="submit"> 提交</button>
</form>
1
2
3
4
5
6
如果是事件函数里面也是可以正常打开的(js调用该函数或者触发该事件还是会被拦截)
下面举例用的是window.open(), 但是对于js创建a标签和form标签模拟点击/提交的效果是一样的
下面可以打开:
<button onclick="openNewWin()">打开</button>
<script>
function openNewWin(){
var newWin = window.open('https://www.baidu.com');
console.log(newWin); // Window https://www.baidu.com/
// 如果打开失败 newWin 为null
}
</script>
1
2
3
4
5
6
7
8
只要不是ajax的回调函数,其他函数都可以正常打开(包括定时器的异步操作函数):
<button onclick="openNewWin()">打开</button>
<script>
function openNewWin(){
function open(url) {
var newWin = window.open(url);
console.log(newWin); // Window https://www.baidu.com/
}
open('https://www.baidu.com');
}
</script>
1
2
3
4
5
6
7
8
9
10
<button onclick="openNewWin()">打开</button>
<script>
function openNewWin(){
setTimeout(() => {
var newWin = window.open('https://www.baidu.com');
console.log(newWin); // Window https://www.baidu.com/
}, 2000);
}
</script>
1
2
3
4
5
6
7
8
9
因此总结js打开新窗口会被拦截的情况有三种,一是非用户触发事件的函数内打开新窗口,二是在ajax的回调函数里面打开新窗口,第三是一次打开多个新窗口,除了第一个,其他都会被拦截。
重点
了解到上面的情况后,解决方法就确定下来了,在用户点击的地方先打开新窗口,然后重定向路由过去(对于新窗口链接确定的情况,如果不确定,如通过form表单post数据到新页面的形式现在暂无解决方案)
<button onclick="openNewWin()">打开</button>
<script>
function openNewWin(){
var newWin = window.open();
setTimeout(() => {
newWin.location.href = 'https://www.baidu.com';
// newWin.close();
}, 2000);
}
</script>
1
2
3
4
5
6
7
8
9
10
我这里的实际业务主要是通过form表单post数据打印pdf,因此解决方法是不新窗口打开,直接让接口返回文件流下载,如此也不会导致页面的刷新。
var pdfDownload = function (template, header, footer, size, filename, datas, as) {
constant.template_name = template ? template : constant.template_name;
constant.header_template = header ? header : constant.header_template;
constant.footer_template = footer ? footer : constant.footer_template;
constant.page_size = size ? size : constant.page_size;
constant.filename = filename ? filename : constant.filename;
constant.datas = datas ? datas : constant.datas;
constant.as = as ? as : constant.as;
var tempForm = document.createElement('form');
tempForm.style.display = "none";
tempForm.method = "POST";
tempForm.action = "/pdfprint";
tempForm.target = !constant.filename ? "_blank" : '';
tempForm = angular.element(tempForm);
constant.forEach(function (v, k) {
if (v) {
var hiddenInput = document.createElement("input");
hiddenInput.name = k;
hiddenInput.value = v;
hiddenInput.type = "hidden";
tempForm.append(hiddenInput);
}
});
angular.element('body').append(tempForm);
tempForm.submit();
tempForm.remove();
}