如何解决Scroll组件嵌套Web组件后无法跟随页面整体滚动的问题
=================================

#### 问题现象

在Scroll组件内嵌套使用Web组件和其他容器组件的组合时，嵌套布局如下：

Scroll() {
  Row() {}
  Web() {}
  Row() {}
  List() {}
}

Web组件显示不全或只能单独滚动，无法实现与Row、List等组件连为一个整体进行滚动。

#### 背景知识

*   [layoutMode](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-basic-components-web-attributes#layoutmode11)：设置Web布局模式。当属性没有显式调用时，默认Web布局跟随系统模式。
*   [RenderMode](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-basic-components-web-e#rendermode12)：定义Web组件的渲染方式，默认为异步渲染模式。建议使用异步渲染模式，异步渲染模式有更好的性能和更低的功耗。

#### 问题定位

从问题现象可以看出当前有两种状态：Web组件会单独滚动以及内容显示不全。

分析两种状态的原因：

1.  Web组件单独滚动是因为固定了组件的高度，且该高度小于内容高度。
2.  Web组件内容显示不全是因为在第1点的基础上禁止了Web的滚动。

#### 分析结论

问题的关键在于如何控制Web组件的高度，让其可以适应内容高度，从而将Web变成一个完全展开的view。

#### 解决方案

通过设置layoutMode属性为WebLayoutMode.FIT\_CONTENT让Web自适应内容高度。

import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebFit {
  webviewController: webview.WebviewController \= new webview.WebviewController();

  build() {
    Scroll() {
      Column() {
        Row() {
          Text('测试顶部');
        }
        .width('100%')
        .height('30%')
        .justifyContent(FlexAlign.Center)
        .backgroundColor(Color.Gray);

     _   // 网页内容过宽或者过长时需要设置为RenderMode.SYNC\_RENDER_
        Web({ src: $rawfile('test.html'), controller: this.webviewController, renderMode: RenderMode.SYNC\_RENDER })
          .width('100%')
          .height('100%')
          .metaViewport(true)
          .layoutMode(WebLayoutMode.FIT\_CONTENT) _// 设置Web组件高度进行自适应_
          .overScrollMode(OverScrollMode.NEVER) _// 关闭过界回弹效果_
          .zoomAccess(false) _// 关闭手势缩放_
          .fileAccess(false)
          .geolocationAccess(false);
        Row() {
          Text('测试底部');
        }
        .width('100%')
        .height('30%')
        .justifyContent(FlexAlign.Center)
        .backgroundColor(Color.Gray);
      };
    };
  }
}

<!DOCTYPE html\>
<html\>
<head\>
    <meta charset\="UTF-8"\>
    <meta name\="viewport" content\="width=device-width, initial-scale=1, user-scalable=no"\>
    <title\>Fit-Content</title\>
</head\>
<body\>
    <p\>这就是一个测试话题。</p\>
    <p\>这就是一个测试话题。</p\>
    <p\>这就是一个测试话题。</p\>
    <p\>这就是一个测试话题。</p\>
    <p\>这就是一个测试话题。</p\>
    <p\>这就是一个测试话题。</p\>
    <p\>这就是一个测试话题。</p\>
    <p\>这就是一个测试话题。</p\>
    <p\>这就是一个测试话题。</p\>
    <p\>这就是一个测试话题。</p\>
    <p\>这就是一个测试话题。</p\>
    <p\>这就是一个测试话题。</p\>
    <p\>这就是一个测试话题。</p\>
    <p\>这就是一个测试话题。</p\>
    <p\>这就是一个测试话题。</p\>
    <p\>这就是一个测试话题。</p\>
    <p\>这就是一个测试话题。</p\>
    <p\>这就是一个测试话题。</p\>
</body\>
</html\>

#### 总结

通过layoutMode属性使Web组件的大小根据页面内容自适应变化，当Web页面宽高超过7680px（物理像素），建议设置渲染模式为同步渲染：renderMode: RenderMode.SYNC\_RENDER。