网页里涉及全屏切换时,很多人会直接在触发按钮上临时找元素,但这样既不利于复用,也不方便后续统计。更稳妥的做法,是先用 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,但对多数场景来说,当前写法已经足够清晰且易维护。
















