JavaScript 中 Set 怎么在网页全屏状态切换时记录支持全屏的元素集合

林见深
林见深
发布时间:2026-08-25| 164人浏览过
原创
浏览器限制与失败场景的手绘专栏图
全屏失败不等于不支持支持全屏和本次全屏成功不是一回事,权限和策略限制需要单独理解。
fullscreenchange 事件更新集合的手绘专栏图
事件触发后的集合更新事件本身不返回目标元素,但可以借助 document.fullscreenElement。
用 Set 预筛网页全屏候选元素的手绘专栏图
初始化全屏候选集合先筛常见标签,再按方法存在与 DOM 状态过滤,得到初始全屏候选集合。

前言

网页里做全屏切换时,真正需要管理的往往不是某一个按钮,而是一组可能进入全屏的候选元素。与其在事件触发时临时查找,不如先用 Set 建一份可维护的集合,再结合 fullscreenchange 动态补记实际进入过全屏的对象,同时把权限限制和失败场景从集合逻辑里剥离开来。

网页里涉及全屏切换时,很多人会直接在触发按钮上临时找元素,但这样既不利于复用,也不方便后续统计。更稳妥的做法,是先用 Set 维护一份“支持全屏的候选元素集合”,再在 fullscreenchange 事件里动态更新,既能自动去重,也能把真正进入过全屏的元素补记下来。本文按“先筛候选、再监听变化、最后处理兼容限制”的顺序展开,读者可以据此判断哪些元素该进集合、哪些失败场景不该误删。

为什么要用 Set 记录全屏候选元素

这里记录的不是“页面上的所有元素”,而是“当前具备全屏能力的候选元素”。这类元素通常需要满足几个基本条件:本身能调用 requestFullscreen()、节点仍然连接在 DOM 中,而且没有落在明显无效的目标类型上。

之所以适合用 Set,原因很直接:

  • 同一个元素被多次扫描或多次进入全屏时,不会重复存储。
  • 初始化扫描和事件监听可以共用同一个集合,不需要手动判重。
  • 后续读取也方便,既可以拿到 fullscreenCandidates.size,也可以用 [...fullscreenCandidates] 转成数组继续处理。

要注意,这个集合表达的是“支持全屏的候选范围”,不是“本次一定成功进入全屏的元素名单”。有些元素具备方法,但会因为权限、策略或上下文限制导致实际调用失败,这两者不能混为一谈。

初始化 Set:先筛出真正可用的候选元素

页面加载后,可以先对常见容器类标签做一次预扫描,但没必要把所有节点一股脑遍历。更实际的方式,是只检查常见的全屏目标,例如 div、section、article、main、video、iframe、canvas。

初始化时建议至少保留两层判断:

  • 用 typeof el.requestFullscreen === 'function' 确认它确实支持全屏方法。
  • 用 el.isConnected 排除已经脱离 DOM 的节点。

这样做可以避开 document、window 之类不适合作为目标的对象,也能减少无意义记录。对于大多数页面来说,这种“按常见标签预筛”的成本足够低,结构也比全量扫描更清晰。

适合加入集合的判断标准

  • 是页面中常见、实际可能被全屏展示的元素。
  • 存在 requestFullscreen 方法,而不是仅仅样式上看起来像容器。
  • 节点仍在当前文档中,避免把已删除元素留下来干扰结果。

监听 fullscreenchange:把真实进入过全屏的元素补进来

fullscreenchange 是这类场景的关键事件。它不会直接告诉你“刚才是哪一个元素触发了全屏”,但事件发生时可以读取 document.fullscreenElement:

  • 如果结果不是 null,说明当前正有某个元素处于全屏状态。
  • 如果结果是 null,说明页面已经退出全屏。

基于这个特性,常见的记录方式有两种:

  • 只关心当前正在全屏的元素:每次读取当前值即可。
  • 想保留历史上所有曾成功全屏过的元素:只要 document.fullscreenElement 存在,就用 add() 写入 Set。

如果你的目标是“记录支持全屏的元素集合”,第二种更实用。因为初始化扫描只能得到理论候选,事件监听则能补上“实际成功进入过全屏”的对象,两者结合后,集合会更完整。

此外,事件更新阶段也要继续过滤无效值,比如避免把 document、shadowRoot 或已经移除的节点误加进去。这里同样可以继续使用 isConnected 做基本校验。

兼容性和权限限制要怎么理解

一个常见误区是:只要元素上有 requestFullscreen,它就一定能成功全屏。实际并不是这样。浏览器对全屏操作还有策略限制,例如:

  • iframe 可能缺少 allow="fullscreen"。
  • 页面可能不在安全上下文里,例如非 HTTPS。
  • 调用时机不符合要求,没有来自用户手势触发。

这时调用可能静默失败,也可能直接抛错。但从集合维护的角度看,这不代表它就不属于“支持全屏的候选元素”。因此,失败尝试不应该导致你把这个元素从 Set 中删除。

更稳妥的做法包括:

  • 在调用前先检查 el.matches(':fullscreen') 或 document.fullscreenElement === el,避免重复请求。
  • 对现代 API 返回的 Promise 做错误捕获,例如 el.requestFullscreen().catch(() => {})。
  • 把“是否支持”与“本次是否成功”分开记录,避免逻辑混乱。

这样一来,Set 承担的是能力集合的职责,而不是一次调用结果的成败日志。

可直接使用的示例代码

下面这段脚本保留了最核心的实现:初始化收集候选元素,随后监听全屏状态变化,并把实际进入全屏的元素补进集合。

const fullscreenCandidates = new Set();

// 初始化:收集页面中明确支持 requestFullscreen 的元素
document.querySelectorAll('div, section, article, main, video, iframe, canvas')
.forEach(el => {
if (typeof el.requestFullscreen === 'function' && el.isConnected) {
fullscreenCandidates.add(el);
}
});

// 监听全屏状态变化
document.addEventListener('fullscreenchange', () => {
const current = document.fullscreenElement;
if (current && typeof current.requestFullscreen === 'function') {
fullscreenCandidates.add(current); // 记录这次实际进入全屏的元素
}
});

// ✅ 使用时可随时读取:[...fullscreenCandidates] 或 fullscreenCandidates.size

这段代码适合解决什么问题

它适合放在需要统一管理全屏目标的页面里,例如视频页、画布编辑器、富媒体展示区或多容器布局页面。它的优势不是“保证所有元素都能全屏成功”,而是用尽量轻量的方式,把当前页面里可参与全屏的对象先整理出来,再结合事件把真实用到的元素持续归档。

如果后续还要扩展,比如区分“候选元素”和“曾成功全屏元素”两类数据,也可以在这个基础上再拆分为两个 Set,但对多数场景来说,当前写法已经足够清晰且易维护。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。