CloseWatcher

可用性有限

此特性不是基线特性,因为它在一些最广泛使用的浏览器中不起作用。

实验性: 这是一项实验性技术
在生产中使用此技术之前,请仔细检查浏览器兼容性表格

CloseWatcher 接口允许具有打开和关闭语义的自定义 UI 组件以与内置组件相同的方式响应特定于设备的关闭操作。

EventTarget CloseWatcher

CloseWatcher 接口继承自 EventTarget

构造函数

CloseWatcher() 实验性

创建一个新的 CloseWatcher 实例。

实例方法

此接口还继承了其父接口 EventTarget 的方法。

CloseWatcher.requestClose() 实验性

触发一个 cancel 事件,如果该事件未被 Event.preventDefault() 取消,则继续触发一个 close 事件,然后像调用 destroy() 一样停用关闭监视器。

CloseWatcher.close() 实验性

立即触发 close 事件,而不先触发 cancel,然后像调用 destroy() 一样停用关闭监视器。

CloseWatcher.destroy() 实验性

停用关闭监视器,使其不再接收 close 事件。

事件

cancel 实验性

close 事件之前触发的事件,以便可以阻止 close 事件触发。

close 实验性

收到关闭请求时触发的事件。

描述

某些 UI 组件具有“关闭行为”,这意味着该组件会出现,并且用户可以在完成使用后将其关闭。例如:侧边栏、弹出窗口、对话框或通知。

用户通常希望能够使用特定的机制来关闭这些元素,并且该机制倾向于特定于设备。例如,在具有键盘的设备上可能是 Esc 键,但 Android 可能会使用返回按钮。对于内置组件,例如 popover<dialog> 元素,浏览器会处理这些差异,并在用户执行适合设备的关闭操作时关闭该元素。但是,当 Web 开发者实现自己的可关闭 UI 组件(例如侧边栏)时,很难实现这种特定于设备的关闭行为。

CloseWatcher 接口通过在用户执行特定于设备的关闭操作时发送 cancel 事件,然后发送 close 事件来解决此问题。Web 应用程序可以使用 onclose 处理程序来响应特定于设备的事件来关闭 UI 元素。它们还可以响应 UI 元素的正常关闭机制来触发相同的事件,然后为应用程序特定和设备特定的关闭操作实现通用的 close 事件处理。一旦 onclose 事件处理程序完成,CloseWatcher 将被销毁,事件将不再触发。

在某些应用程序中,UI 元素可能只允许在特定状态下关闭;例如,在填充了某些必需信息后。为了解决这些情况,应用程序可以通过实现 cancel 事件的处理程序来阻止 close 事件的发出,如果 UI 元素尚未准备好关闭,则该处理程序会调用 Event.preventDefault()

您可以创建 CloseWatcher 实例而无需 用户激活,这对于实现会话不活动超时对话框等场景很有用。但是,如果您在没有用户激活的情况下创建多个 CloseWatcher,则这些监视器将被分组,因此一次关闭请求将同时关闭它们。此外,第一个关闭监视器不一定是 CloseWatcher 对象:它可能是一个模态对话框元素,或者是由带有 popover 属性的元素生成的 popover。

示例

处理关闭请求

在此示例中,您有自己的 UI 组件(一个选择器),并且希望同时支持平台的默认关闭方法(例如 Esc 键)和自定义关闭方法(一个关闭按钮)。

您创建一个 CloseWatcher 来处理所有 close 事件。

您的 UI 组件的 onclick 处理程序可以调用 requestClose 来请求关闭,并将您的关闭请求路由到与平台关闭方法相同的 onclose 处理程序。

js
const watcher = new CloseWatcher();
const picker = setUpAndShowPickerDOMElement();
let chosenValue = null;

watcher.onclose = () => {
  chosenValue = picker.querySelector("input").value;
  picker.remove();
};

picker.querySelector(".close-button").onclick = () => watcher.requestClose();

使用平台关闭请求关闭侧边栏

在此示例中,我们有一个侧边栏组件,当选择“打开”按钮时显示,并使用“关闭”按钮或平台原生机制进行隐藏。为了更有趣,这是一个实时示例!

还要注意,该示例有点牵强,因为通常我们会使用切换按钮来更改侧边栏状态。我们当然可以这样做,但使用单独的“打开”和“关闭”按钮可以更轻松地演示该功能。

HTML

HTML 定义了“打开”和“关闭” <button> 元素,以及用于主内容和侧边栏的 <div> 元素。CSS 用于在将 open 类添加到侧边栏和内容元素或从中删除时为侧边栏元素显示设置动画(此 CSS 已隐藏,因为它与示例无关)。

html
<button id="sidebar-open" type="button">Open</button>
<button id="sidebar-close" type="button">Close</button>
<div class="sidebar">Sidebar</div>
<div class="main-content">Main content</div>

JavaScript

代码首先获取 HTML 中定义的按钮和 <div> 元素的变量。它还定义了一个 closeSidebar() 函数,该函数在关闭侧边栏时调用,以从 <div> 元素中删除 open 类,并添加了一个 click 事件侦听器,该侦听器在单击“打开”按钮时调用 openSidebar() 方法。

js
const sidebar = document.querySelector(".sidebar");
const mainContent = document.querySelector(".main-content");
const sidebarOpen = document.getElementById("sidebar-open");
const sidebarClose = document.getElementById("sidebar-close");

function closeSidebar() {
  sidebar.classList.remove("open");
  mainContent.classList.remove("open");
}

sidebarOpen.addEventListener("click", openSidebar);

openSidebar() 的实现如下。该方法首先检查侧边栏是否已打开,如果没有,则将 open 类添加到元素,以便显示侧边栏。

然后我们创建一个新的 CloseWatcher,并添加一个侦听器,当单击“关闭”按钮时,该侦听器将对其调用 close()。这确保了在使用平台原生关闭方法或“关闭”按钮时都调用 close 事件。onclose() 事件处理程序的实现只是关闭侧边栏,然后 CloseWatcher 会自动销毁。

js
function openSidebar() {
  if (!sidebar.classList.contains("open")) {
    sidebar.classList.add("open");
    mainContent.classList.add("open");

    // Add new CloseWatcher
    const watcher = new CloseWatcher();

    sidebarClose.addEventListener("click", () => watcher.close());

    // Handle close event, invoked by platform mechanisms or "Close" button
    watcher.onclose = () => {
      closeSidebar();
    };
  }
}

请注意,我们选择在监视器上调用 close() 而不是 CloseWatcher.requestClose(),因为我们不需要发出 cancel 事件(如果我们有理由阻止侧边栏过早关闭,我们将使用 requestClose()cancel 事件处理程序)。

结果

选择“打开”按钮以打开侧边栏。您应该能够使用“关闭”按钮或通常的平台方法(例如 Windows 上的 Esc 键)关闭侧边栏。

规范

规范
HTML
# closewatcher

浏览器兼容性

另见