uni-app 项目使用的自定义底部tab栏配置safearea后,使用video组件开启全屏再退出全屏时底部safearea失效

uni-app 项目使用的自定义底部tab栏配置safearea后,使用video组件开启全屏再退出全屏时底部safearea失效

开发环境 版本号 项目创建方式
Windows 10 HBuilderX
### 操作步骤:
1. manifest.json设置了safearea
2. 项目使用自定义的底部tab栏
3. 二级页面内使用video组件,全屏播放后退出全屏
4. 返回到项目首页
5. 再进入任何一个页面
6. 页面的内容没有全屏显示,底部safearea的区域内显示了上一个页面的内容

### 预期结果:
- safearea不失效

### 实际结果:
- safearea失效,页面高度没有撑满全屏,导致显示了上一个页面的内容

### bug描述:
在manifest.json设置了safearea,
```javascript
"safearea" : {  
    //安全区域配置,仅iOS平台生效  
    "background" : "#FFFFFF", //安全区域外的背景颜色,默认值为"#FFFFFF"  
    "bottom" : {  
        // 底部安全区域配置  
        "offset" : "auto" // 底部安全区域偏移,"none"表示不空出安全区域,"auto"自动计算空出安全区域,默认值为"none"  
    },  
    "left" : {  
        //左侧安全区域配置(横屏显示时有效)  
        "offset" : "auto"  
    },  
    "right" : {  
        //右侧安全区域配置(横屏显示时有效)  
        "offset" : "auto"  
    }  
}

项目使用的自定义的底部tab栏,在首页进入二级页面,video组件全屏播放后退出全屏,返回首页,底部的safearea失效,再进入一个二级页面,该页面底部的safearea区域内会显示上一个页面的内容


更多关于uni-app 项目使用的自定义底部tab栏配置safearea后,使用video组件开启全屏再退出全屏时底部safearea失效的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于uni-app 项目使用的自定义底部tab栏配置safearea后,使用video组件开启全屏再退出全屏时底部safearea失效的实战教程也可以访问 https://www.itying.com/category-93-b0.html


这是一个已知的uni-app框架与原生组件交互时的兼容性问题。当video组件全屏播放时,会触发原生全屏模式,退出全屏后页面布局可能出现异常。

问题原因: video组件作为原生组件,在全屏切换时会改变页面渲染层级和布局计算。退出全屏后,safearea的CSS变量(如–window-bottom)可能未能正确更新,导致页面高度计算错误。

解决方案:

  1. 强制刷新布局:在页面onShow生命周期中手动重置页面高度
onShow() {
  // 重置页面布局
  uni.getSystemInfo({
    success: (res) => {
      this.$nextTick(() => {
        // 强制更新样式
      })
    }
  })
}
  1. 监听全屏事件:在video组件的fullscreenchange事件中处理
<video @fullscreenchange="handleFullscreenChange"></video>

handleFullscreenChange(e) {
  if(!e.detail.fullScreen) {
    // 退出全屏时重新计算布局
    setTimeout(() => {
      uni.pageScrollTo({
        scrollTop: 0,
        duration: 0
      })
    }, 100)
  }
}
  1. 使用CSS修复:在页面样式中显式设置安全区域
.page-container {
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}
  1. 临时方案:在返回首页时添加短暂延迟
uni.navigateBack({
  success: () => {
    setTimeout(() => {
      // 触发页面重绘
    }, 50)
  }
})
回到顶部