在新标签页中打开URL(而不是新窗口)

2813

我正在尝试在新标签页中打开一个URL,而不是弹出窗口。

我看到了类似的问题,其响应大致如下:

window.open(url,'_blank');
window.open(url);

但是这些方法都没有对我起作用,浏览器仍然试图打开一个弹出窗口。


96
通常这是个人偏好的问题。有些人喜欢用窗口(并强烈坚持这种行为),有些人喜欢用标签页(也同样强烈坚持)。因此,你要改变的是一种通常被认为是品味问题而非设计问题的行为方式。 - Jared Farrish
56
JavaScript 不了解您的浏览器、选项卡和窗口之间的区别,所以打开新窗口的方式完全由浏览器决定。 - Andrey
8
我该如何配置Chrome在新标签页中显示页面,而不是弹出窗口? - Mark
13
在Chrome中,Gmail可以通过某种方式实现此功能。按住Shift并单击电子邮件行即可在新窗口中打开该邮件。按住Ctrl并单击则将其在新标签页中打开。唯一的问题是:深入挖掘Gmail的代码可能非常麻烦。 - Sergio
58
@Sergio,这是任何链接的默认浏览器行为(至少适用于 Chrome 和 Firefox),与 Gmail 无关。 - Qtax
显示剩余13条评论
33个回答

20
无论是在新标签页还是新窗口中打开URL,实际上由用户的浏览器偏好控制。在JavaScript中无法覆盖这一设置。 window.open()的行为取决于其使用方式。如果它作为用户操作(例如按钮单击)的直接结果被调用,它应该能够正常工作并打开一个新的标签页(或窗口):
const button = document.querySelector('#openTab');

// add click event listener
button.addEventListener('click', () => {
    // open a new tab
    const tab = window.open('https://attacomsian.com', '_blank');
});

然而,如果您尝试从AJAX请求回调中打开一个新标签页,则浏览器将阻止该操作,因为它不是直接用户动作。

要绕过弹出窗口拦截程序并在回调中打开一个新标签页,可以使用以下小技巧

const button = document.querySelector('#openTab');

// add click event listener
button.addEventListener('click', () => {

    // open an empty window
    const tab = window.open('about:blank');

    // make an API call
    fetch('/api/validate')
        .then(res => res.json())
        .then(json => {

            // TODO: do something with JSON response

            // update the actual URL
            tab.location = 'https://attacomsian.com';
            tab.focus();
        })
        .catch(err => {
            // close the empty window
            tab.close();
        });
});

不确定为什么这个被投票否决了 - 这对我有用,而且似乎是在回调中打开选项卡的聪明方法。 - stevex
@stevex — 这回答与问题所问的完全不同。这个答案是关于与弹出窗口拦截器交互,而不是在将用户浏览器偏好设置为打开新窗口时打开一个新标签页。 - Quentin

17

如果省略strWindowFeatures参数,将会打开一个新的标签页,除非浏览器设置覆盖它(浏览器设置胜过JavaScript)。

新窗口

var myWin = window.open(strUrl, strWindowName, [strWindowFeatures]);

新标签页

var myWin = window.open(strUrl, strWindowName);

-- 或者 --

var myWin = window.open(strUrl);

16

如果您正试图从自定义函数中打开新选项卡,则与浏览器设置无关。

在此页面中,打开JavaScript控制台并键入:

document.getElementById("nav-questions").setAttribute("target", "_blank");
document.getElementById("nav-questions").click();

无论您的设置如何,它都将尝试打开弹出窗口,因为“click”来自自定义操作。

为了像实际的链接点击一样运行,您需要遵循spirinvladimir的建议并且真正地创建它:

document.getElementById("nav-questions").setAttribute("target", "_blank");
document.getElementById("nav-questions").dispatchEvent((function(e){
  e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0,
                    false, false, false, false, 0, null);
  return e
}(document.createEvent('MouseEvents'))));

这是一个完整的示例(不要在jsFiddle或类似的在线编辑器上尝试,因为它不会允许你从那里重定向到外部页面):

<!DOCTYPE html>
<html>
<head>
  <style>
    #firing_div {
      margin-top: 15px;
      width: 250px;
      border: 1px solid blue;
      text-align: center;
    }
  </style>
</head>

<body>
  <a id="my_link" href="http://www.google.com"> Go to Google </a>
  <div id="firing_div"> Click me to trigger custom click </div>
</body>

<script>
  function fire_custom_click() {
    alert("firing click!");
    document.getElementById("my_link").dispatchEvent((function(e){
      e.initMouseEvent("click", true, true, window, /* type, canBubble, cancelable, view */
            0, 0, 0, 0, 0,              /* detail, screenX, screenY, clientX, clientY */
            false, false, false, false, /* ctrlKey, altKey, shiftKey, metaKey */
            0, null);                   /* button, relatedTarget */
      return e
    }(document.createEvent('MouseEvents'))));
  }
  document.getElementById("firing_div").onclick = fire_custom_click;
</script>
</html>

1
我最终采用了另一种解决方案,其中我执行 w = window.open("placeholder"); $.ajax(...ajax调用返回url...) success (...w.location = data.url...),参考 http://theandystratton.com/2012/how-to-bypass-google-chromes-javascript-popup-blocker。 - Paul Tomblin
14
这并不完全正确。这仍然取决于浏览器的设置。HTML或JavaScript规范中没有声明“自定义操作”必须在弹出窗口中打开而不是选项卡中打开。实际上,我的电脑上没有任何一个浏览器显示这种行为。 - nmclean

13
(function(a) {
    document.body.appendChild(a);
    a.setAttribute('href', location.href);
    a.dispatchEvent((function(e) {
        e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, true, false, false, false, 0, null);
        return e
    }(document.createEvent('MouseEvents'))))
}(document.createElement('a')))

13
function openTab(url) {
  const link = document.createElement('a');
  link.href = url;
  link.target = '_blank';
  document.body.appendChild(link);
  link.click();
  link.remove();
}

1
这可能会在新标签页或窗口中打开,具体取决于浏览器设置。问题特别涉及在新标签页中打开,即使偏好设置为新窗口。 - Quentin
1
我认为这是最干净的解决方案。 - Kar.ma
需要进行解释。例如,这个想法/主旨是什么?它与之前的答案有何不同(例如提到的浏览器配置依赖项)?测试了哪个浏览器,包括版本?来自帮助中心:“...始终解释为什么您提出的解决方案是合适的以及它如何工作”。请通过编辑(更改)您的答案进行回复,而不是在此处进行评论(*** 不要 ***使用“编辑:”,“更新:”或类似内容 - 答案应该看起来像今天写的)。 - Peter Mortensen
答案不言自明。 - iamandrewluca

12

你可以使用一个关于form的技巧:

$(function () {
    $('#btn').click(function () {
        openNewTab("http://stackoverflow.com")
        return false;
    });
});

function openNewTab(link) {
    var frm = $('<form   method="get" action="' + link + '" target="_blank"></form>')
    $("body").append(frm);
    frm.submit().remove();
}

jsFiddle演示


5
如果你采用这种方法,请确保 URL 没有查询参数,因为它们将被表单提交跳过。一种解决方案是在表单元素内嵌入隐藏的输入元素,这些元素具有名称作为键和查询参数内所有参数的值作为值。然后提交表单。 - Mudassir Ali
иҝҷеҸҜд»Ҙжӣҙз®ҖеҚ•ең°дҪҝз”Ёaж ҮзӯҫиҖҢдёҚжҳҜиЎЁеҚ•пјҢ并дҪҝз”ЁjQueryзҡ„.click()ж–№жі•жқҘвҖңжҸҗдәӨвҖқгҖӮиҜ·жҹҘзңӢжҲ‘зҡ„зӯ”жЎҲгҖӮ - user3186555

10

不要使用target="_blank"

始终为该窗口使用特定的名称,在我的情况下是meaningfulName。这样可以节省处理器资源:

button.addEventListener('click', () => {
    window.open('https://google.com', 'meaningfulName')
})

这样,当您点击一个按钮10次时,浏览器将始终在一个新标签页中重新渲染它,而不是在10个不同的标签页中打开它,这将消耗更多的资源。

您可以在MDN上了解更多相关信息。


6

jQuery

$('<a />',{'href': url, 'target': '_blank'}).get(0).click();

JavaScript

Object.assign(document.createElement('a'), { target: '_blank', href: 'URL_HERE'}).click();

这可能根据浏览器设置在新标签页或窗口中打开。问题是即使偏好设置为新窗口,也要特别打开在新标签页中。 - Quentin

5

要在新标签页中打开并保持在同一位置,您可以在新标签页中打开当前页面,并将旧标签页重定向到新的URL。

let newUrl = 'http://example.com';
let currentUrl = window.location.href;
window.open(currentUrl , '_blank'); // Open window with the URL of the current page
location.href = newUrl; // Redirect the previous window to the new URL

您将会被浏览器自动转移到一个新打开的选项卡。这看起来像是页面重新加载,但您仍然停留在同一页上,只不过在新窗口中打开了它。

Enter image description here


1
问题是关于当用户的偏好是在新窗口中打开选项卡时如何打开新选项卡。它并不是在同时打开另一个 URL 的同时在现有选项卡中打开一个新 URL 的问题。 - Quentin
1
如果安装了广告拦截器,这将无法正常工作。当前标签页将被广告拦截器关闭。 - Saqib Omer

4
或者您可以创建一个链接元素并单击它...
var evLink = document.createElement('a');
evLink.href = 'http://' + strUrl;
evLink.target = '_blank';
document.body.appendChild(evLink);
evLink.click();
// Now delete it
evLink.parentNode.removeChild(evLink);

这不应该被任何弹出窗口拦截器阻止...希望如此。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接