Teleport实现移动端规格弹窗需四步:一、挂载到body专属容器避免transform干扰;二、用inset+safe-area适配全屏与异形屏;三、禁用body滚动并支持上滑关闭;四、监听全屏状态动态切换Teleport目标。
在移动端商城中,规格弹窗需要全屏沉浸式体验——既要遮住整个视口、支持手势滑动关闭、适配刘海屏/异形屏,又不能被商品详情页的 transform 或 overflow: hidden 干扰。Vue 的 Teleport 是实现这一效果的核心,但仅写 <Teleport to="body"> 远不够。关键在于动态目标 + 视口级定位 + 移动端专属样式策略。
移动端页面常有 .page-wrapper、.scroll-container 等带 transform: translateZ(0) 或 overflow: hidden 的祖先节点,它们会截断 fixed 定位并创建独立层叠上下文。若把弹窗传送到 #app 或某个业务 div 内,就会失效。
to="body",并在 <body> 底部手动添加一个纯净容器:<div id="teleport-spec-root"></div>
<Teleport to="#teleport-spec-root">,便于后续统一加 transition、防滚动穿透等全局控制to=".spec-modal" 或 to="#app" —— 这些节点大概率自带 transform/filter/overflow不是“填满屏幕”就行,而是要真正覆盖 viewport,适配各种安卓/iOS 状态栏和安全区域。
position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;(不用 100% 防止缩放抖动)inset: 0; 替代 top/left/width/height(更简洁,兼容 Safari 15.4+)padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
background: rgba(0, 0, 0, 0.75); backdrop-filter: blur(6px);(iOS 支持良好,安卓部分需加 -webkit- 前缀)弹窗打开时,背后页面仍可滚动,这是移动端大忌;同时用户习惯上滑关闭,需主动支持。
<body> 加 style="overflow: hidden; touch-action: none;"(关闭后记得还原)touchstart + touchmove 判断是否从顶部向下拖拽(deltaY > 40),触发关闭逻辑overscroll-behavior-y: contain;,防止拖拽到底部时触发页面回弹transform: translateY(100%) + opacity: 0,配合 will-change: transform; 提升性能当用户点击商品视频进入浏览器原生全屏(video.requestFullscreen()),此时 body 已不是渲染主层——所有挂载到 body 的弹窗会被“关在外面”。
fullscreenchange 事件,检测 document.fullscreenElement
<video>),将 Teleport 的 to 动态切换为该元素:to="document.fullscreenElement"
#teleport-spec-root,避免残留position: fixed,需改用 position: absolute; inset: 0; 并手动处理安全区