vue-screenfull
v1.1.3
Published
Reactive, strongly typed, SSR-safe fullscreen utilities for Vue 3.
Downloads
708
Maintainers
Readme
vue-screenfull
vue-screenfull 为 Vue 3 提供响应式、强类型的全屏控制。在服务端渲染
(Server-Side Rendering,SSR) 期间也可以安全导入该软件包。原生任意元素全屏不可用时,可以启用
CSS 伪全屏回退方案。
安装
在 Vue 3.3 或更高版本的项目中安装软件包:
npm install vue-screenfull软件包根入口 vue-screenfull 提供 Vue 组合式函数、组件、指令和插件。该入口在运行时需要
Vue 3。Vue 被标记为可选的对等依赖,因此只使用框架无关入口 vue-screenfull/browser 的项目
无需安装 Vue。
默认浏览器 IIFE 位于 lib/vue-screenfull.min.js。它会暴露 VUE_SCREENFULL,并要求通过全局
变量 Vue 访问 Vue。
无 Vue 浏览器入口
如果调用方没有 Vue 根实例,请使用 vue-screenfull/browser。该子路径只导出 createScreenfullController、detectFullscreenApi 和框架无关的类型。运行时不会加载 Vue 或 Mazey。
通过 npm 使用:
import { createScreenfullController } from "vue-screenfull/browser";
const controller = createScreenfullController({ restoreFocus: true });
const target = document.querySelector("#player");
const button = document.querySelector("#toggle-fullscreen");
const toggle = () => controller.toggle(target);
button?.addEventListener("click", toggle);
async function dispose() {
button?.removeEventListener("click", toggle);
await controller.destroy();
}
// 集成销毁时调用 dispose()。通过浏览器原生 ES 模块使用:
<script type="module">
import { createScreenfullController } from "https://cdn.jsdelivr.net/npm/vue-screenfull/lib/browser.mjs";
const controller = createScreenfullController();
const target = document.querySelector("#player");
const button = document.querySelector("#toggle-fullscreen");
const toggle = () => controller.toggle(target);
button?.addEventListener("click", toggle);
async function dispose() {
button?.removeEventListener("click", toggle);
await controller.destroy();
}
// 集成销毁时调用 dispose()。
</script>通过经典脚本使用:
<script src="https://cdn.jsdelivr.net/npm/vue-screenfull/lib/vue-screenfull.browser.min.js"></script>
<script>
const controller = VUE_SCREENFULL_BROWSER.createScreenfullController();
const target = document.querySelector("#player");
const button = document.querySelector("#toggle-fullscreen");
const toggle = () => controller.toggle(target);
button?.addEventListener("click", toggle);
function dispose() {
button?.removeEventListener("click", toggle);
return controller.destroy();
}
// 集成销毁时调用 dispose()。
</script>请在点击、键盘或触摸事件处理程序中直接调用 request 或 toggle。浏览器通常要求短暂的用户激活状态。请保留控制器,并在集成销毁时调用 destroy()。该方法会清理监听器和正在运行的 CSS 回退方案。
浏览器支持
本项目在运行时检测功能。当前桌面版 Chrome、Edge、Firefox 和 Safari 通常会提供该 API。Android 上的 Chrome、Firefox 和 Samsung Internet 通常也会提供。iPadOS 上的 Safari 通常也支持该 API。iPhone Safari 和 Android/iOS WebView 可能限制任意元素全屏。受管理设备和嵌入式文档也可能存在限制。此策略描述目标平台,不保证支持每个操作系统或浏览器版本。
原生全屏可以隐藏更多浏览器界面,但浏览器和操作系统仍保留控制权。CSS 回退方案只会填满可视视口,不会声称能够隐藏系统或浏览器界面。
基本用法
<script setup lang="ts">
import { ref } from "vue";
import { useScreenfull } from "vue-screenfull";
const target = ref<HTMLElement | null>(null);
const { isEnabled, isFullscreen, error, toggle } = useScreenfull();
</script>
<template>
<section ref="target">
<p>Fullscreen content</p>
<button type="button" :disabled="!isEnabled" @click="toggle(target)">
{{ isFullscreen ? "Exit fullscreen" : "Enter fullscreen" }}
</button>
<p v-if="error" role="alert">{{ error.message }}</p>
</section>
</template>请在点击、键盘或触摸事件处理程序中直接调用 request 或 toggle。浏览器通常要求短暂的用户激活状态。即使 isEnabled.value 为 true,浏览器也可能拒绝请求。
将指定元素设为全屏
<script setup lang="ts">
import { ref } from "vue";
import { useScreenfullTarget } from "vue-screenfull";
const panel = ref<HTMLElement | null>(null);
const { request, isFullscreen } = useScreenfullTarget(panel);
</script>
<template>
<section ref="panel">
<button type="button" @click="request()">Open panel</button>
<span>Active: {{ isFullscreen }}</span>
</section>
</template>调用 useScreenfull().request() 时可以不传目标。此时会打开 document.documentElement。可以将 "#player" 等选择器传给 request。document.querySelector 会解析这些选择器。无效或未匹配的选择器会返回 INVALID_TARGET。
切换全屏状态
const result = await toggle(target, { navigationUI: "hide" });
if (!result.ok) console.warn(result.error.code, result.error.suggestion);对于图片内容,请传入图片的模板引用。HTMLVideoElement 也是有效目标。如果视频演示需要自定义
控件,请将视频及其控件放入同一个容器,并将该容器设为目标。这样可以确保原生或回退全屏模式下
仍能使用这些控件。部分移动浏览器提供由浏览器管理的视频全屏功能,该功能与任意元素全屏相互独立。
退出全屏
<button type="button" @click="exit">Exit fullscreen</button>请在全屏目标内保留可见的退出按钮,启用回退方案时尤其如此。Escape 键通常可以退出,但无法可靠地覆盖浏览器的 Escape 键行为。通过浏览器界面发起的退出操作会由原生变更事件反映。
检查支持情况
const { isEnabled, status } = useScreenfull();
// isEnabled.value: native API currently enabled
// status.value: idle | requesting | fullscreen | exiting | fallback | unsupported | error在 Safari、iOS/iPadOS 和 WebView 中,功能检测比用户代理检查更可靠。
处理错误
const result = await request(target);
if (!result.ok) {
console.error(
result.error.code,
result.error.message,
result.error.suggestion,
);
}错误类型可以区分不支持的环境或 SSR 环境,以及无效或已分离的目标。它还能区分用户激活状态、权限和 iframe 策略。其他类型包括待处理的转换、原生请求或退出失败,以及回退失败。调用 clearError() 前,error 会保留最近一次错误。
CSS 回退方案
const { request, exit, isFallback } = useScreenfull({
fallback: "css",
fallbackClass: "my-pseudo-fullscreen",
lockScroll: true,
restoreFocus: true,
});CSS 回退方案会将 HTMLElement 固定到可视视口。它会保留自身修改的所有内联样式。对于元素目标,它会锁定背景页面的滚动,并在退出后恢复。整个页面作为目标时仍可滚动。它还会保留滚动位置并添加配置的类。它会尽可能响应 Escape 键退出并恢复焦点。Vue 作用域销毁时也会执行清理。
这是伪全屏模式,无法隐藏地址栏、浏览器控件、通知或操作系统界面。请在目标元素中保留易于访问的退出按钮:
<button type="button" @click="exit">Close full-page view</button>自定义回退方案需要实现 enter(context) 和 exit(context)。该方案负责完成所有清理工作。
组件用法
<Screenfull
target="#article"
fallback="css"
v-slot="screenfull"
@error="report"
>
<article id="article">
<button type="button" @click="screenfull.toggle()">
{{ screenfull.isFullscreen.value ? "Exit" : "Open article" }}
</button>
</article>
</Screenfull>无渲染组件会触发 change、enter、exit、error 和 fallback 事件。其默认插槽接收组合式
函数的所有引用和操作。组件不会施加任何视觉样式。screenfull 是作用域插槽对象,因此需要使用
.value 访问其中嵌套的 ref。
指令用法
<button v-screenfull>Fullscreen page</button>
<button v-screenfull="target">Toggle target</button>
<button v-screenfull:request="target">Enter target</button>
<button v-screenfull:exit>Exit</button>
<button
v-screenfull="{ target, action: 'toggle', options: { navigationUI: 'hide' } }"
>Toggle</button>仅支持 request、exit 和 toggle 参数,默认为 toggle。除非已安装插件,否则需要在本地注册指令:
const vScreenfull = importedDirective;安装插件
import { createApp } from "vue";
import VueScreenfull from "vue-screenfull";
import App from "./App.vue";
createApp(App).use(VueScreenfull).mount("#app");这会注册 Screenfull 和 v-screenfull。可以通过 componentName 和 directiveName 更改名称。具名导入组合式函数时无需安装插件,且仍可进行摇树优化。
高级用法
框架无关的控制器适用于迁移和非组件集成:
import { createScreenfullController } from "vue-screenfull/browser";
const controller = createScreenfullController({ restoreFocus: true });
const onChange = (state) => console.log(state.isFullscreen, state.element);
controller.on("change", onChange);
await controller.request(document.querySelector("#map"));
controller.off("change", onChange);
await controller.destroy();raw 是检测到的浏览器属性或事件名称的只读诊断映射,也可能为 null。不建议将其作为 API 使用。每个组合式函数都会创建一个控制器,并随 Vue 作用域销毁。多个控制器通过同一文档的原生事件保持同步。导入此软件包不会注册监听器或访问 DOM。
响应式回调可以观察变更,无需重复连接组件:
useScreenfull({ onEnter: announce, onExit: announce, onError: report });restoreFocus: true (默认值) 会在退出后尽可能恢复焦点。焦点会移回触发操作的元素。exitOnRouteChange 会监听浏览器的 popstate。对于路由器特有的导航,可以改为在应用自身的路由钩子中调用 exit()。
iframe 用法
嵌入页面负责控制权限。典型的 iframe 如下:
<iframe
src="https://example.com/player"
allow="fullscreen"
allowfullscreen
></iframe>Permissions Policy 或缺少 iframe 权限仍可能导致拒绝。如果拒绝与嵌入式文档有关,库会返回 IFRAME_PERMISSION_REQUIRED。库无法覆盖父页面的策略。
移动端注意事项
- 使用直接的用户手势,并保留可见且便于触控的退出控件。
- 使用功能检测,不要根据设备名称推断支持情况。
- iPhone Safari 和 WKWebView 可能受限,也可能仅支持视频全屏。
- 动态浏览器界面会改变视口高度;CSS 回退方案会在支持时使用
100dvh。 - 原生导航、切换标签页、切换应用和操作系统手势可能退出全屏。
- 原生功能和本库都无法保证浏览器或操作系统控件消失。
SSR 和 Nuxt
在 Vite SSR、Nuxt 3、Node 测试和静态生成中可以安全导入。在浏览器外,isEnabled 为 false,状态为 unsupported。此时操作会返回 NOT_IN_BROWSER。
<script setup lang="ts">
import { useScreenfull } from "vue-screenfull";
const screenfull = useScreenfull(); // safe during Nuxt setup/SSR
</script>
<template>
<ClientOnly>
<button
type="button"
:disabled="!screenfull.isEnabled.value"
@click="screenfull.toggle()"
>
Toggle page fullscreen
</button>
</ClientOnly>
</template>在 <script setup> 中解构引用时,模板会自动解包。像上面的示例一样通过对象访问时,请在脚本表达式中使用 .value。
从 screenfull 迁移
vue-screenfull 是独立的 Vue 3 库。其设计灵感来自 screenfull 的公共 API 和兼容性目标。它不能作为直接替代品,也未获得 screenfull 维护者的认可。
| screenfull 概念 | vue-screenfull 对应项 |
| -------------------------------------- | -------------------------------- |
| screenfull.request(element, options) | request(element, options) |
| screenfull.exit() | exit() |
| screenfull.toggle(element, options) | toggle(element, options) |
| screenfull.isEnabled | 响应式 isEnabled.value |
| screenfull.isFullscreen | 响应式 isFullscreen.value |
| screenfull.element | 响应式 fullscreenElement.value |
| screenfull.on("change", fn) | 引用、回调、组件事件或控制器事件 |
| screenfull.on("error", fn) | 响应式 error、回调或控制器事件 |
迁移前:
import screenfull from "screenfull";
if (screenfull.isEnabled) await screenfull.toggle(element);迁移后:
import { useScreenfull } from "vue-screenfull";
const { isEnabled, toggle } = useScreenfull();
if (isEnabled.value) {
const result = await toggle(element);
if (!result.ok) console.error(result.error.message);
}主要区别包括响应式引用、自动清理生命周期和支持 SSR 的安全导入。还包括结构化结果和错误、可选伪全屏,以及 Vue 组件和指令 API。控制器监听器接收带类型的状态或错误,而非原始 DOM 事件。项目未提供旧版 onchange 或 onerror 别名。插件为可选功能。
API 参考
根导出如下:
useScreenfull(options?)、useScreenfullTarget(target, options?)Screenfull、vScreenfull和默认插件createScreenfullController(options?)detectFullscreenApi(document)和resolveScreenfullTarget(target, document)- 所有公开的目标、选项、状态、结果、错误、事件、组件、指令、插件和原始映射类型
操作会解析为 { ok, mode, element, error }。mode 为 native、fallback 或 none。生成的 TypeDoc 发布于 API 文档网站。
vue-screenfull/browser 子路径只导出 createScreenfullController、detectFullscreenApi 和框架无关的控制器类型。
在线演练场
已部署的版本位于 vue-screenfull 在线演练场。其中包含页面、元素、图片样式和视频目标。它还提供显式退出、诊断、无效目标反馈和事件历史记录。其他内容包括无障碍、iframe、移动端和迁移说明。使用以下命令在本地运行:
npm run dev浏览器会强制要求用户激活,因此本项目不会将原生全屏自动化视为在所有环境中均可靠。
可安装的文档网站
项目网站是渐进式 Web 应用 (Progressive Web App,PWA)。其作用域为 /vue-screenfull/。首页、演练场和 API 文档共享生成的清单和 Google Workbox v7 Service Worker。文档、脚本和样式使用容量受限的网络优先缓存。它通常会优先使用最新文档,避免新 HTML 与旧软件包搭配使用。本地图片和字体使用容量受限的缓存优先存储。只有当网络和运行时缓存均无法提供请求的文档时,才会使用预缓存的离线页面。
如果浏览器支持,安装功能会使用原生 beforeinstallprompt 流程。网站不会自动打开该提示。不支持自定义提示的浏览器可以使用菜单;在 iOS/iPadOS Safari 上,可以使用 共享 → 添加到主屏幕。安装此网站与 Fullscreen API 相互独立,不会授予全屏功能。
Worker 更新仍由用户控制。有新版本等待更新时,选择 立即更新 即可激活版本,并重新加载当前页面一次。在演练场中,此显式操作是唯一会重新加载活动会话的更新方式。生成的 Worker 包含最终产物版本标记。它无需预缓存未进行版本控制的软件包,也能检测到可部署的网站变更。
开发
npm install
npm run typecheck
npm run lint
npm run format:check
npm run test
npm run build
npm run docs
npm run seo:validate
npm run pwa:validate
npm run preview
npm pack --dry-run常规的 npm run dev 不会注册生产环境 Worker。若要在类似生产环境中测试 PWA,请运行 npm run docs。然后在 localhost 的 /vue-screenfull/ 路径下提供生成的 docs 目录。
有关浏览器矩阵和真实浏览器测试策略,请参阅 guides/MANUAL_TESTING.md。根入口会生成以下文件:
lib/index.cjs.jslib/index.esm.jslib/index.mjslib/vue-screenfull.min.jslib/index.d.tslib/typing.d.tslib/global.d.ts
框架无关的入口会生成以下文件:
lib/browser.cjs.jslib/browser.esm.jslib/browser.mjslib/browser.d.tslib/vue-screenfull.browser.min.js
JavaScript 软件包会包含源映射。
许可证与致谢
本项目根据 MIT License 发布。screenfull (MIT) 的公共 API 和跨浏览器兼容性为本项目提供了灵感。vue-fullscreen (MIT) 是 Vue 生态系统参考。以上内容不表示相关项目对本项目的认可。
