页面跳转时，有渐入渐出的动效
==============

#### 问题现象

页面跳转时，有渐入渐出的动效，新旧页面内容出现重叠显示。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/6d/v3/0b_WsKYDQ1qjEkStCdCzIQ/zh-cn_image_0000002658961879.png?HW-CC-KV=V1&HW-CC-Date=20260709T134022Z&HW-CC-Expire=86400&HW-CC-Sign=CFA79BE9172636724DEA0FB515D4B3591520E8822FA6797509D6D2F27AD6721C "点击放大")

#### 背景知识

*   [Web](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-basic-components-web)组件提供网页显示的能力。
*   [transition](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-transition-animation-component)是基础的组件转场接口，用于实现一个组件出现或者消失时的动画效果。

#### 问题定位

1.  使用DevEco Testing查看该页面的组件，跳转前后的页面分别通过不同的Web组件显示。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/2c/v3/pL34YSmpQWGDknxNWG4Olw/zh-cn_image_0000002628602668.png?HW-CC-KV=V1&HW-CC-Date=20260709T134022Z&HW-CC-Expire=86400&HW-CC-Sign=44A5313CB9DEC5D5C911FC5899059902ABDD530A2FF1960D12A745A09B7F9F55 "点击放大")
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/d8/v3/gX4259b6TKCl0UcYgTU_bA/zh-cn_image_0000002658841939.png?HW-CC-KV=V1&HW-CC-Date=20260709T134022Z&HW-CC-Expire=86400&HW-CC-Sign=7419D5E6551BFA0CA9D23E290257F67F63CF8D79C11FF97814B2367735E5B3B4 "点击放大")
    
2.  查看跳转之后的Web组件的相关设置，发现应用transition属性设置了透明度渐变的过渡效果。
    
    import { webview } from '@kit.ArkWeb';
    
    @Entry
    @Component
    struct WebVideo {
      controller: webview.WebviewController = new webview.WebviewController();
      @State isShowNewWeb: boolean = false;
    
      build() {
        Stack() {
          Column() {
            Web({ src: $rawfile('VideoList.html'), controller: this.controller })
              .height('100%')
              .width('100%')
              .fileAccess(true)
              .geolocationAccess(false)
              .onLoadIntercept((event) => {
                if (event.data.getRequestUrl() === 'resource://rawfile/index\_cn.html') {
                  this.isShowNewWeb = true;
                  return true; _// 拦截此次跳转_
                } else {
                  return false; _// 允许跳转_
                }
              });
          };
    
          if (this.isShowNewWeb) {
            Web({ src: $rawfile('index\_cn.html'), controller: this.controller })
              .height('100%')
              .width('100%')
              .fileAccess(true)
              .geolocationAccess(false)
              .transition(TransitionEffect.OPACITY.animation({ duration: 2000, curve: Curve.Ease })); _// 设置透明度渐变的过渡效果_
          }
        }
        .height('100%')
        .width('100%');
      }
    }
    

#### 分析结论

在页面跳转过程中，使用新的Web组件呈现内容，同时对跳转后的Web组件应用transition属性设置了透明度渐变转场效果。

#### 修改建议

*   方案一：不使用新的Web组件来显示页面，而是在原来的Web组件上进行页面跳转。
    
    import { webview } from '@kit.ArkWeb';
    
    @Entry
    @Component
    struct SolutionOne {
      controller: webview.WebviewController = new webview.WebviewController();
    
      build() {
        Stack() {
          Column() {
            Web({ src: $rawfile('VideoList.html'), controller: this.controller })
              .height('100%')
              .width('100%')
              .fileAccess(true)
              .geolocationAccess(false)
           _ // 不对视频播放页面进行拦截，在原来的Web组件上进行页面跳转_
          };
        }
        .height('100%')
        .width('100%');
      }
    }
    
    src/main/resources/rawfile/VideoList.html：
    
    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <title>视频列表</title>
        <style>
            body {
              font-family: 'Segoe UI', sans-serif;
              margin: 0;
              padding: 20px;
              color: #333;
            }
    
            _/\* 视频列表容器 \*/_
            .video-list {
              display: grid;
              grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)));
              gap: 20px;
              max-width: 1400px;
              margin: 0 auto;
            }
    
            _/\* 视频卡片 \*/_
            .video-card {
              display: flex;           _/\* 启用 Flexbox \*/_
              background-color: #f1f3f5;
              border-radius: 12px;
              overflow: hidden;
              transition: all 0.3s ease;
              position: relative;
            }
    
            .video-text {
              text-align: center;
              width: 100px;
              margin-top: 40px;
            }
    
            .video-thumbnail {
              width: 150px;
              height: 100px;
              object-fit: contain;
              display: block;
              margin-left: 10px;
            }
    
        </style>
    </head>
    <body>
    
    <h1 style="font-size: 16px;">视频列表</h1>
    
    <div class="video-list">
       _ <!-- 视频项 1 -->_
        <div class="video-card" onclick="newPage()">
            _<!-- "img/poster1.PNG"需要替换为开发者需要的图片资源文件 -->_
            <img src="img/poster1.PNG" alt="视频封面" class="video-thumbnail">
            <div class="video-text"> 视频1</div>
        </div>
    
       _ <!-- 视频项 2 -->_
        <div class="video-card">
           _ <!-- "img/poster2.PNG"需要替换为开发者需要的图片资源文件 -->_
            <img src="img/poster2.PNG" alt="视频封面" class="video-thumbnail">
            <div class="video-text"> 视频2</div>
        </div>
    </div>
    
    <script>
        function newPage() {
           _ // 跳转到新页面_
            window.location.href = "./index\_cn.html";
        }
    </script>
    
    </body>
    </html>
    
    src/main/resources/rawfile/index\_cn.html：
    
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>测试页面</title>
        <style>
            \* {
                padding: 0;
                margin: 0;
            }
    
            body {
                width: 100vw;
                height: 100vh;
                box-sizing: border-box;
            }
    
            .page {
                display: flex;
                flex-direction: column;
                justify-content: flex-start;
                align-items: flex-start;
                width: 100%;
                height: 100%;
                box-sizing: border-box;
            }
    
            .video-box {
                width: 100%;
                display: flex;
                flex-direction: column;
                justify-content: start;
                align-items: center;
                box-sizing: border-box;
                margin-top: 20px;
            }
    
            .myVideo {
                width: 100%;
                height: calc(100vw \* 9 / 16);
                object-fit: contain;
                background-color: black;
            }
        </style>
    </head>
    
    <body>
    <div class="page">
        <h1 style="margin-left: 100px;margin-top: 20px">网页视频显示</h1>
        <div class="video-box">
            <video autoplay muted loop class="myVideo" controls>
               _ <!-- "www.example.mp4"需要替换为开发者需要的视频资源文件 -->_
                <source src="www.example.mp4" type="video/mp4">
            </video>
        </div>
    
        <div style="margin-top: 40px; margin-left: 20px">
            <h2>视频简介</h2>
            <div style="margin-top: 10px">
                该网页视频为示例视频
            </div>
        </div>
    </div>
    
    </body>
    
    </html>
    
    效果图如下：
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/27/v3/5uxF_pEQRmem0_EZQ4MxjQ/zh-cn_image_0000002628762568.png?HW-CC-KV=V1&HW-CC-Date=20260709T134022Z&HW-CC-Expire=86400&HW-CC-Sign=80145083437A8977BF75DE6A07A71F2D494EE191D7081588625D11771165D1B6 "点击放大")
    
*   方案二：跳转后的Web组件不设置透明度渐变的过渡效果。
    
    import { webview } from '@kit.ArkWeb';
    
    @Entry
    @Component
    struct SolutionTwo {
      controller: webview.WebviewController = new webview.WebviewController();
      @State isShowNewWeb: boolean = false;
    
      build() {
        Stack() {
          Column() {
            Web({ src: $rawfile('VideoList.html'), controller: this.controller })
              .height('100%')
              .width('100%')
              .fileAccess(true)
              .geolocationAccess(false)
              .onLoadIntercept((event) => {
                console.info('url:' + event.data.getRequestUrl());
                if (event.data.getRequestUrl() === 'resource://rawfile/index\_cn.html') {
                  this.isShowNewWeb = true;
                  return true; _// 拦截此次跳转_
                } else {
                  return false; _// 允许跳转_
                }
              });
          };
    
          if (this.isShowNewWeb) {
            Web({ src: $rawfile('index\_cn.html'), controller: this.controller })
              .height('100%')
              .width('100%')
              .fileAccess(true)
              .geolocationAccess(false)
        _    // 不设置透明度由浅到深的转场效果_
          }
        }
        .height('100%')
        .width('100%');
      }
    }
    
    src/main/resources/rawfile/VideoList.html：
    
    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <title>视频列表</title>
        <style>
            body {
              font-family: 'Segoe UI', sans-serif;
              margin: 0;
              padding: 20px;
              color: #333;
            }
    
           _ /\* 视频列表容器 \*/_
            .video-list {
              display: grid;
              grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)));
              gap: 20px;
              max-width: 1400px;
              margin: 0 auto;
            }
    
           _ /\* 视频卡片 \*/_
            .video-card {
              display: flex;          _ /\* 启用 Flexbox \*/_
              background-color: #f1f3f5;
              border-radius: 12px;
              overflow: hidden;
              transition: all 0.3s ease;
              position: relative;
            }
    
            .video-text {
              text-align: center;
              width: 100px;
              margin-top: 40px;
            }
    
            .video-thumbnail {
              width: 150px;
              height: 100px;
              object-fit: contain;
              display: block;
              margin-left: 10px;
            }
    
        </style>
    </head>
    <body>
    
    <h1 style="font-size: 16px;">视频列表</h1>
    
    <div class="video-list">
       _ <!-- 视频项 1 -->_
        <div class="video-card" onclick="newPage()">
           _ <!-- "img/poster1.PNG"需要替换为开发者需要的图片资源文件 -->_
            <img src="img/poster1.PNG" alt="视频封面" class="video-thumbnail">
            <div class="video-text"> 视频1</div>
        </div>
    
       _ <!-- 视频项 2 -->_
        <div class="video-card">
          _  <!-- "img/poster2.PNG"需要替换为开发者需要的图片资源文件 -->_
            <img src="img/poster2.PNG" alt="视频封面" class="video-thumbnail">
            <div class="video-text"> 视频2</div>
        </div>
    </div>
    
    <script>
        function newPage() {
      _      // 跳转到新页面_
            window.location.href = "./index\_cn.html";
        }
    </script>
    
    </body>
    </html>
    
    src/main/resources/rawfile/index\_cn.html：
    
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>测试页面</title>
        <style>
            \* {
                padding: 0;
                margin: 0;
            }
    
            body {
                width: 100vw;
                height: 100vh;
                box-sizing: border-box;
            }
    
            .page {
                display: flex;
                flex-direction: column;
                justify-content: flex-start;
                align-items: flex-start;
                width: 100%;
                height: 100%;
                box-sizing: border-box;
            }
    
            .video-box {
                width: 100%;
                display: flex;
                flex-direction: column;
                justify-content: start;
                align-items: center;
                box-sizing: border-box;
                margin-top: 20px;
            }
    
            .myVideo {
                width: 100%;
                height: calc(100vw \* 9 / 16);
                object-fit: contain;
                background-color: black;
            }
        </style>
    </head>
    
    <body>
    <div class="page">
        <h1 style="margin-left: 100px;margin-top: 20px">网页视频显示</h1>
        <div class="video-box">
            <video autoplay muted loop class="myVideo" controls>
              _  <!-- "www.example.mp4"需要替换为开发者需要的视频资源文件 -->_
                <source src="www.example.mp4" type="video/mp4">
            </video>
        </div>
    
        <div style="margin-top: 40px; margin-left: 20px">
            <h2>视频简介</h2>
            <div style="margin-top: 10px">
                该网页视频为示例视频
            </div>
        </div>
    </div>
    
    </body>
    
    </html>
    
    效果图如下：
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/22/v3/GWQrGvIzRwGcRwyfDktZFw/zh-cn_image_0000002658961881.png?HW-CC-KV=V1&HW-CC-Date=20260709T134022Z&HW-CC-Expire=86400&HW-CC-Sign=9CB0B4D0AB8FC0A556FEC7C634F8B84D005254F103F783832B944E899D22D8AE "点击放大")