Window: open() 方法

open()Window 接口的一个方法,它会在指定的名称下,将指定的资源加载到新的或现有的浏览上下文(即选项卡、窗口或 iframe)中。

语法

js
open()
open(url)
open(url, target)
open(url, target, windowFeatures)

参数

url 可选

一个字符串,指示要加载的资源的 URL 或路径。如果指定空字符串 ("") 或省略此参数,则会在目标浏览上下文中打开一个空白页面。

target 可选

一个不包含空格的字符串,指定要将资源加载到的浏览上下文的 名称。如果该名称未识别任何现有上下文,则会创建一个新的上下文并赋予其指定的名称。还可以使用特殊的 target 关键字_self_blank(默认)、_parent_top_unfencedTop_unfencedTop 仅与 fenced frames 相关。

此名称可以用作 <a><form> 元素的 target 属性。

windowFeatures 可选

一个字符串,包含以 name=value 形式表示的窗口功能的逗号分隔列表。布尔值可以使用以下其中一种方式设置为 true:namename=yesname=truename=n,其中 n 是任何非零整数。这些功能包括窗口的默认大小和位置、是否打开最小弹出窗口等选项。支持以下选项

attributionsrc 实验性功能

指示您希望浏览器在 open() 调用期间发送 Attribution-Reporting-Eligible 标头。此调用必须使用 瞬时激活(即在用户交互事件处理程序(如 click)内)在用户交互的五秒钟内进行。在服务器端,这用于触发在响应中发送 Attribution-Reporting-Register-Source 标头,以完成归因来源的注册。

此外,当 open() 方法完成时,还会触发浏览器存储关联的源数据(如 Attribution-Reporting-Register-Source 响应标头中提供的那样)。

有关更多详细信息,请参阅 归因报告 API

注意:open() 调用不能用于注册归因触发器。

默认情况下,window.open 会在新选项卡中打开页面。如果 popup 设置为 true,则它会请求使用最小的弹出窗口。弹出窗口中包含的 UI 功能将由浏览器自动确定,通常仅包括地址栏。如果 popup 存在且设置为 false,则仍会打开一个新选项卡。

有一些旧版功能,过去用于控制已打开窗口的 UI 功能。在现代浏览器中,它们只会起到请求弹出窗口的作用。如果 popup 未指定,并且 windowFeatures 包含除 noopenernoreferrerattributionsrc 之外的任何功能(包括无法识别的功能),则如果满足以下任何条件,该窗口也会以弹出窗口的形式打开

  • locationtoolbar 均为 false 或不存在
  • menubar 为 false 或不存在
  • resizable 为 false
  • scrollbars 为 false 或不存在
  • status 为 false 或不存在

否则,窗口将以选项卡的形式打开。

widthinnerWidth

指定内容区域的宽度,包括滚动条。最小所需值为 100。

heightinnerHeight

指定内容区域的高度,包括滚动条。最小所需值为 100。

leftscreenX

指定新窗口将在用户操作系统定义的工作区域左侧的像素距离。

topscreenY

指定新窗口将在用户操作系统定义的工作区域顶部的像素距离。

noopener

如果设置了此功能,则新窗口将无法通过 Window.opener 访问原始窗口,并返回 null

当使用 noopener 时,除 _top_self_parent 之外的非空目标名称在决定是否打开新的浏览上下文方面与 _blank 相同。

noreferrer

如果设置了此功能,浏览器将省略 Referer 标头,并将 noopener 设置为 true。有关更多信息,请参阅 rel="noreferrer"

null 值的处理方式与空字符串 ("") 相同。

注意:如果 windowFeatures 中的任何请求值都不允许将整个浏览器弹出窗口呈现到用户操作系统的应用程序的工作区域内,则会更正请求的位置 (topleft) 和请求的尺寸 (widthheight) 值。换句话说,新弹出窗口的任何部分最初都不能位于屏幕外。

返回值

如果浏览器成功打开了新的浏览上下文,则会返回一个 WindowProxy 对象。只要它符合 同源策略 安全要求,就可以使用返回的引用访问新上下文的属性和方法。

如果浏览器无法打开新的浏览上下文,例如由于浏览器弹出窗口阻止程序阻止了它,则会返回 null

描述

Window 接口的 open() 方法以 URL 作为参数,并将它标识的资源加载到新的或现有的选项卡或窗口中。target 参数确定将资源加载到哪个窗口或选项卡中,而 windowFeatures 参数可用于控制打开具有最少 UI 功能的新弹出窗口,并控制其大小和位置。

远程 URL 不会立即加载。当 window.open() 返回时,窗口始终包含 about:blank。URL 的实际获取会被延迟,并在当前脚本块执行完成后开始。窗口创建和引用的资源加载是异步完成的。

现代浏览器具有严格的弹出窗口阻止程序策略。弹出窗口必须直接响应用户输入打开,并且每个 Window.open() 调用都需要一个单独的用户手势事件。这可以防止网站向用户发送大量窗口。但是,这会给多窗口应用程序带来问题。要解决此限制,您可以设计应用程序以

  • 一次最多打开一个新窗口。
  • 重用现有窗口以显示不同的页面。
  • 建议用户如何更新其浏览器设置以允许多个窗口。

示例

打开新选项卡

js
window.open("https://www.mozilla.org/", "mozillaTab");

打开弹出窗口

或者,以下示例演示了如何使用 popup 功能打开弹出窗口。

js
window.open("https://www.mozilla.org/", "mozillaWindow", "popup");

可以控制新弹出窗口的大小和位置

js
const windowFeatures = "left=100,top=100,width=320,height=320";
const handle = window.open(
  "https://www.mozilla.org/",
  "mozillaWindow",
  windowFeatures,
);
if (!handle) {
  // The window wasn't allowed to open
  // This is likely caused by built-in popup blockers.
  // …
}

渐进增强

在某些情况下,JavaScript 被禁用或不可用,并且 window.open() 将无法工作。我们不应仅依赖此功能的存在,而应提供替代解决方案,以便网站或应用程序仍然能够正常运行。

在 JavaScript 被禁用时提供替代方法

如果禁用了 JavaScript 支持或不存在 JavaScript 支持,则用户代理将相应地创建辅助窗口,或根据其对 target 属性的处理来呈现引用的资源。目标和理念是为用户提供(而非强加)一种打开引用的资源的方法。

HTML

html
<a href="https://www.wikipedia.org/" target="OpenWikipediaWindow">
  Wikipedia, a free encyclopedia (opens in another, possibly already existing,
  tab)
</a>

JavaScript

js
let windowObjectReference = null; // global variable
function openRequestedTab(url, windowName) {
  if (windowObjectReference === null || windowObjectReference.closed) {
    windowObjectReference = window.open(url, windowName);
  } else {
    windowObjectReference.focus();
  }
}

const link = document.querySelector("a[target='OpenWikipediaWindow']");
link.addEventListener(
  "click",
  (event) => {
    openRequestedTab(link.href);
    event.preventDefault();
  },
  false,
);

以上代码解决了与链接打开弹出窗口相关的一些可用性问题。代码中 event.preventDefault() 的目的是取消链接的默认操作:如果执行了 click 的事件侦听器,则无需执行链接的默认操作。但是,如果用户浏览器上禁用了或不存在 JavaScript 支持,则会忽略 click 的事件侦听器,浏览器将在名为 "WikipediaWindowName" 的目标框架或窗口中加载引用的资源。如果没有框架或窗口名为 "WikipediaWindowName",则浏览器将创建一个新窗口并将其命名为 "WikipediaWindowName"

注意:有关 target 属性的更多详细信息,请参阅 <a><form>

重用现有窗口并避免使用 target="_blank"

使用"_blank"作为target属性值会在用户的桌面上创建多个新的、未命名的窗口,这些窗口无法回收或重用。尝试为您的target属性提供一个有意义的名称,并在您的页面上重用此target属性,以便点击另一个链接可以在已创建并呈现的窗口中加载引用的资源(从而加快用户的处理速度),从而证明创建辅助窗口的理由(以及用户系统资源、花费的时间)。使用单个target属性值并在链接中重用它更友好地利用用户资源,因为它只创建了一个辅助窗口,并且该窗口会被回收。

以下是一个可以打开和重用辅助窗口以用于其他链接的示例。

HTML

html
<p>
  <a href="https://www.wikipedia.org/" target="SingleSecondaryWindowName">
    Wikipedia, a free encyclopedia (opens in another, possibly already existing,
    tab)
  </a>
</p>
<p>
  <a
    href="https://support.mozilla.org/products/firefox"
    target="SingleSecondaryWindowName">
    Firefox FAQ (opens in another, possibly already existing, tab)
  </a>
</p>

JavaScript

js
let windowObjectReference = null; // global variable
let previousURL; /* global variable that will store the
                    url currently in the secondary window */
function openRequestedSingleTab(url) {
  if (windowObjectReference === null || windowObjectReference.closed) {
    windowObjectReference = window.open(url, "SingleSecondaryWindowName");
  } else if (previousURL !== url) {
    windowObjectReference = window.open(url, "SingleSecondaryWindowName");
    /* if the resource to load is different,
       then we load it in the already opened secondary window and then
       we bring such window back on top/in front of its parent window. */
    windowObjectReference.focus();
  } else {
    windowObjectReference.focus();
  }
  previousURL = url;
  /* explanation: we store the current url in order to compare url
     in the event of another call of this function. */
}

const links = document.querySelectorAll(
  "a[target='SingleSecondaryWindowName']",
);
for (const link of links) {
  link.addEventListener(
    "click",
    (event) => {
      openRequestedSingleTab(link.href);
      event.preventDefault();
    },
    false,
  );
}

同源策略

如果新打开的浏览上下文不共享相同的来源,则打开脚本将无法与浏览上下文的内容进行交互(读取或写入)。

js
// Script from example.com
const otherOriginContext = window.open("https://example.org");
// example.com and example.org are not the same origin

console.log(otherOriginContext.origin);
// DOMException: Permission denied to access property "origin" on cross-origin object
js
// Script from example.com
const sameOriginContext = window.open("https://example.com");
// This time, the new browsing context has the same origin

console.log(sameOriginContext.origin);
// https://example.com

有关更多信息,请参阅同源策略文章。

无障碍访问问题

避免使用window.open()

最好避免使用window.open(),原因如下:

  • 现代浏览器提供弹出窗口阻止功能。
  • 现代浏览器提供选项卡式浏览,在大多数情况下,支持选项卡的浏览器用户更喜欢打开新选项卡而不是打开新窗口。
  • 用户可以使用浏览器内置功能或扩展程序来选择是在新窗口、同一窗口、新选项卡、同一选项卡或后台打开链接。使用window.open()强制以特定方式打开链接会让用户感到困惑并忽略他们的习惯。
  • 弹出窗口没有菜单工具栏,而新选项卡使用浏览器窗口的用户界面;因此,许多用户更喜欢选项卡式浏览,因为界面保持稳定。

切勿在HTML中内联使用window.open()

避免使用<a href="#" onclick="window.open(…);"><a href="javascript:window\.open(…)" …>

这些虚假的href值会导致在复制/拖动链接、在新选项卡/窗口中打开链接、添加书签或在 JavaScript 加载、错误或禁用时出现意外行为。它们还会向辅助技术(如屏幕阅读器)传递不正确的语义。

如有必要,请改用<button>元素。一般来说,您应该只将链接用于导航到真实的URL

以有助于用户导航的方式识别将打开新窗口的链接。

html
<a target="WikipediaWindow" href="https://www.wikipedia.org">
  Wikipedia (opens in new tab)
</a>

目的是警告用户上下文变化,以最大程度地减少用户混淆:更改当前窗口或弹出新窗口可能会让用户感到非常困惑(对于弹出窗口,没有工具栏提供“上一步”按钮以返回到上一个窗口)。

当在发生之前明确识别极端的上下文变化时,用户可以决定是否继续,或者他们可以为更改做好准备:不仅他们不会感到困惑或迷失方向,而且更有经验的用户可以更好地决定如何打开此类链接(在新窗口中或不在新窗口中,在同一窗口中或不在同一窗口中,在新选项卡中或不在新选项卡中,“后台”中或不在“后台”中)。

规范

规范
HTML 标准
# dom-open-dev
CSSOM 视图模块
# open() 方法的功能参数

浏览器兼容性

BCD 表格仅在浏览器中加载

另请参阅