HarmonyOS鸿蒙Next中设置Web容器高度自适应后,全屏播放视频显示异常问题

HarmonyOS鸿蒙Next中设置Web容器高度自适应后,全屏播放视频显示异常问题 【问题描述】:设置Web容器高度自适应后,Web容器高度高度可能会超出100%,而此时又无法强制设置Web容器高度为100%

【问题现象】:在 Web 混合开发中,当 Web 容器设置为高度自适应(Web容器根据富文本内容动态撑高),而富文本内嵌有

cke_3942.png

【版本信息】:6.0.0

【复现代码】:可提供

【尝试解决方案】:使用scroller嵌套无法解决


更多关于HarmonyOS鸿蒙Next中设置Web容器高度自适应后,全屏播放视频显示异常问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

开发者您好,请您参考以下方案,如果未能解决您的问题,请您再反馈:

非全屏/退出全屏状态下页面设置自适应,可以设置一个layoutModeValue变量用来更改layoutMode属性,当非全屏/退出全屏时设置layoutModeValue值为WebLayoutMode.FIT_CONTENT,当全屏时设置layoutModeValue值为WebLayoutMode.NONE,这样全屏后会根据视频的固有尺寸来决定其显示高度。示例如下:

import { webview } from '@kit.ArkWeb';
import { AppUtil, ResUtil } from '@pura/harmony-utils';

@Entry
@Component
struct Index {
  private scroller: Scroller = new Scroller();
  private webViewController: webview.WebviewController = new webview.WebviewController();
  private fullScreenHandler?: FullScreenExitHandler;
  @State layoutModeValue:WebLayoutMode = WebLayoutMode.FIT_CONTENT
  @State isFullScreen: boolean = false;

  onBackPress(): boolean | void {
    if (this.isFullScreen) {
      this.fullScreenHandler?.exitFullScreen();
      this.layoutModeValue = WebLayoutMode.FIT_CONTENT
      return true;
    }
    return false;
  }

  // 加载文章数据
  loadNewsData() {
    // 读取html模板
    let htmlCode = ResUtil.getRawFileContentStrSync('html/html_standard_code.html');

    // 替换标题、来源、发布日期等
    htmlCode = htmlCode.replace('_{title}_', '测试带视频富文本');
    htmlCode = htmlCode.replace('_{source}_', '**日报');
    htmlCode = htmlCode.replace('_{publishTime}_', '2026-03-17 09:05');

    this.webViewController.loadData(htmlCode, "text/html", "UTF-8", "data");
  }

  build() {

    Column() {
      Column() {
        Scroll(this.scroller) {
          Column() {
            // 原生组件
            Text('Native')
              .fontSize(28)
              .fontColor('#FF0F0F')
              .height(100)
              .width('100%')
              .backgroundColor('#f89f0f')
              .textAlign(TextAlign.Center)

            // Web组件
            Web({
              controller: this.webViewController,
              src: "",
              renderMode: RenderMode.SYNC_RENDER, // 设置为同步渲染模式
            })
              .width('100%')
              .layoutMode(this.layoutModeValue) // 动态设置Web组件大小自适应
              .overScrollMode(OverScrollMode.NEVER) // 设置过滚动模式为关闭状态
              .geolocationAccess(false)
              .zoomAccess(false)
              .fileAccess(true)
              .javaScriptAccess(true)
              .domStorageAccess(true)
              .mixedMode(MixedMode.All)
              .verticalScrollBarAccess(false)
              .onControllerAttached(() => {
                // 加载html
                this.loadNewsData()
              })
              .onFullScreenEnter((event) => {
                this.fullScreenHandler = event.handler;
                //this.changeOrientation(window.Orientation.LANDSCAPE);
                this.isFullScreen = true;
                this.layoutModeValue = WebLayoutMode.NONE
              })
              .onFullScreenExit(() => {
                //this.changeOrientation(window.Orientation.PORTRAIT);
                this.isFullScreen = false;
                this.layoutModeValue = WebLayoutMode.FIT_CONTENT
              })

            // 原生组件
            Text('Native')
              .fontSize(28)
              .fontColor('#FF0F0F')
              .height(150)
              .width('100%')
              .backgroundColor('#f89f0f')
              .textAlign(TextAlign.Center)
          }
        }
      }
      .width('100%')
      .layoutWeight(1)
    }
    .width('100%')
    .height('100%')
  }
}

更多关于HarmonyOS鸿蒙Next中设置Web容器高度自适应后,全屏播放视频显示异常问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


有相关的代码吗,可以一起看一下

在HarmonyOS Next中,Web容器高度自适应后全屏播放视频异常,通常是由于WebView全屏模式与系统UI层冲突导致。可尝试通过调整WebView的布局参数,或在视频全屏时动态修改容器尺寸来解决。检查是否启用了正确的硬件加速选项。

这是一个在Web混合开发中比较典型的问题,核心在于Web容器的高度自适应逻辑与视频全屏播放的机制存在冲突。

问题根因分析: 当Web容器(例如WebViewWeb组件)设置为高度自适应(如height: autoheight: fit-content)时,其高度由内部文档流(DOM)内容动态决定。此时,容器本身并没有一个明确的、与屏幕视口关联的100%高度。

当内嵌的<video>元素触发全屏播放时,浏览器/Web引擎的全屏API默认会尝试将触发全屏的元素或其最近的合适容器填充整个屏幕。由于你的Web容器高度是自适应的,且内容可能很长,其实际高度很可能远大于屏幕物理高度。全屏操作会以这个“超长”的容器当前高度作为基准进行缩放和填充,导致视频无法正确匹配设备屏幕的宽高比,出现显示异常(如视频被拉伸、裁剪或周围出现巨大黑边)。

关键点: 视频全屏的是Web容器内的一个上下文,这个上下文的大小受限于Web容器自身的尺寸,而非设备的物理屏幕。

解决方案思路:

你需要干预视频元素进入全屏时的行为,确保全屏的上下文是基于设备屏幕的,而不是基于滚动的Web容器。这通常需要通过JavaScript监听全屏事件,并动态调整样式。

  1. 监听全屏变化:在Web页面的JavaScript代码中,监听fullscreenchange事件。
  2. 动态应用全屏样式:当检测到视频元素进入全屏时,通过CSS强制将视频元素或其直接父元素的定位、尺寸设置为与视口(100vh, 100vw)匹配,并覆盖其他可能影响布局的样式。
  3. 退出时恢复:当退出全屏时,移除这些强制样式。

示例代码片段(Web页面侧JavaScript):

// 监听全屏变化
document.addEventListener('fullscreenchange', handleFullscreenChange);
document.addEventListener('webkitfullscreenchange', handleFullscreenChange); // 兼容WebKit
document.addEventListener('mozfullscreenchange', handleFullscreenChange); // 兼容Firefox
document.addEventListener('MSFullscreenChange', handleFullscreenChange); // 兼容IE/Edge

function handleFullscreenChange() {
    const videoElement = document.querySelector('video'); // 或你的具体视频元素选择器
    const isFullscreen = document.fullscreenElement || 
                         document.webkitFullscreenElement || 
                         document.mozFullScreenElement || 
                         document.msFullscreenElement;

    if (isFullscreen && isFullscreen.tagName.toLowerCase() === 'video') {
        // 进入全屏:为视频元素应用全屏优化样式
        // 关键:使其脱离文档流,并固定到视口
        isFullscreen.style.position = 'fixed';
        isFullscreen.style.top = '0';
        isFullscreen.style.left = '0';
        isFullscreen.style.width = '100vw';
        isFullscreen.style.height = '100vh';
        isFullscreen.style.zIndex = '9999'; // 确保在最上层
        // 可能需要的附加样式,确保视频填充方式正确
        isFullscreen.style.objectFit = 'contain'; // 或 'cover',根据需求
    } else {
        // 退出全屏:移除或重置样式
        // 注意:这里需要针对刚刚进入全屏的那个video元素,这里简单处理,实际情况可能需要遍历或标记
        const videos = document.querySelectorAll('video');
        videos.forEach(video => {
            video.style.position = '';
            video.style.top = '';
            video.style.left = '';
            video.style.width = '';
            video.style.height = '';
            video.style.zIndex = '';
            video.style.objectFit = '';
        });
    }
}

HarmonyOS侧注意事项:

  • 确保你的Web组件配置允许JavaScript执行,并且具有足够的权限。
  • 如果Web内容高度动态变化剧烈,可能需要考虑在容器层面设置overflow: hidden或使用max-height进行约束,但这只是辅助,核心解决方案仍在Web页面脚本中。
  • 测试时注意不同视频播放器控件和浏览器内核的细微差异。

这个方案的本质是将全屏视频从“文档流中一个很长的容器内的一个元素”转变为“一个覆盖在设备屏幕最上层的固定定位元素”,从而绕过自适应容器高度对全屏上下文的限制。

回到顶部