疑难排查

iOS Safari 的怪癖、视频播放、全屏与键盘导航的修复办法。

iOS Safari

视口没有铺满屏幕 / 底部出现黑边

Safari 可收起的地址栏会让 100vh 高于实际可见区域。改用 100dvh:

css
.slider-container {
  height: 100dvh; /* not 100vh */
}

横向滚动 / 内容溢出

在 iOS 上, 100vw 把滚动条宽度也算了进去,内容会被推出屏幕边缘。改用 100% 并锁住横向溢出:

css
html, body {
  overflow-x: hidden;
}

.slider-container {
  width: 100%; /* not 100vw */
}

下拉刷新 / 橡皮筋回弹

Safari 的下拉刷新和弹性回弹会和竖向滑动手势打架。不要把 overscroll-behavior: none 加在 html, body 上,那会把正常的页面滚动也一起废掉。ReelPlayerOverlay、 LightboxOverlay 和 StoriesPlayerOverlay 会在各自的容器上处理好这件事。自定义布局请把它限定在自己的容器里:

css
.slider-container {
  overscroll-behavior: none;
}

SwipeToClose 向下滑动的边界情况。 任何 direction="down" 的 SwipeToClose(Lightbox、Stories Player、自定义浮层)在 iOS Safari 上都会被抢先处理 —— 浏览器在包装层看到触摸事件之前,就已经从文档层级触发了下拉刷新。 浮层虽然锁住了 body 滚动,但根节点的竖向拖拽仍然归浏览器管。 只在浮层打开期间把 overscroll-behavior-y: contain 限定在 <html> 上,关闭时再还原:

tsx
useEffect(() => {
  if (!isOpen) return;
  const html = document.documentElement;
  const prev = html.style.overscrollBehaviorY;
  html.style.overscrollBehaviorY = 'contain';
  return () => {
    html.style.overscrollBehaviorY = prev;
  };
}, [isOpen]);

双指缩放干扰手势

关掉缩放,避免滑动过程中触发捏合和双击:

html
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover" />

viewport-fit=cover 会把布局延伸到灵动岛 / 刘海的安全区域里。

键盘收起后布局错乱

键盘关闭后,Safari 有时会让视口保持被压缩的状态。在失焦时强制重置:

tsx
// React
<input
  onBlur={() => {
    window.scrollTo(0, 0);
    apiRef.current?.adjust();
  }}
/>

// Angular
(blur)="onInputBlur()"

onInputBlur() {
  window.scrollTo(0, 0);
  this.reelApi?.adjust();
}

通用

幻灯片渲染出来是 0×0

不传 size 属性时,滑动器会通过 ResizeObserver 读取容器尺寸。没有 CSS 高度的容器量出来就是 0×0,于是什么都渲染不出来。要么传 size,要么给容器一个尺寸:

css
/* The parent must have a height for auto-sizing to work */
.slider-container {
  width: 100%;
  height: 100dvh;
}

视频

视频不自动播放

浏览器会拦截非静音的自动播放。ReelKit 给每个 video 元素都设了 muted 和 playsInline。视频以静音开始,用户点一下声音开关就能取消静音。 请检查自定义幻灯片里有没有覆盖掉这两个属性。

视频缩略图 / 抽帧是空白

抽帧是把视频画到 <canvas> 上。跨域视频会污染画布,绘制会静默失败。你的视频 CDN 必须返回 CORS 响应头:

text
Access-Control-Allow-Origin: *

ReelKit 默认会设置 crossOrigin="anonymous"。如果你用的是自定义 video 元素,请自己加上。

全屏

Safari 上全屏按钮没反应

ReelKit 在 Safari 上禁用了 Fullscreen API。iOS Safari 只允许 <video> 元素进入全屏;桌面版 Safari 在全屏状态下会弄坏 position: fixed 的浮层:元素会丢失层叠上下文,或者干脆消失。在 Safari 上, requestFullscreen() 会当作空操作直接完成。

键盘导航

传了 onNavKeyPress 之后方向键就不翻页了

onNavKeyPress 是替换掉默认的键盘导航。ReelKit 不再调用 next()/prev(),而是把控制权交给你。需要你自己调用它们:

tsx
<Reel
  onNavKeyPress={(increment) => {
    // Your custom logic here
    console.log('Nav key:', increment);
    // You must trigger navigation yourself:
    apiRef.current?.[increment === 1 ? 'next' : 'prev']();
  }}
/>

按 Escape 关不掉浮层

键盘控制器只负责方向键。ReelPlayerOverlay 和 LightboxOverlay 各自单独监听 Escape。如果你自己写浮层,请在 onClose 里加上自己的 Escape 处理。