如何实现Web组件在Navigation页面中返回上一页
============================

#### 问题现象

在Navigation导航的页面中使用Web组件加载H5页面时，如何实现以下功能：

1.  Web组件和Navigation导航共用一个返回按钮。
2.  侧边返回H5页面的上一页。

#### 背景知识

在HarmonyOS中，通过[WebviewController](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-webview-webviewcontroller)对象控制Web组件，实现返回H5页面中上一页的功能，通常需要对返回操作进行拦截后自定义内容，以下是可能会涉及到的组件属性：

*   [accessBackward](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-webview-webviewcontroller#accessbackward)：判断当前页面是否可后退，即当前页面是否有返回历史记录。
*   [backward](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-webview-webviewcontroller#backward)：按照Web历史栈，后退一个页面。
*   [onBackPressed](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navdestination#onbackpressed10)：Navigation默认提供的返回按钮，返回值为true时，表示重写返回键逻辑，返回值为false时，表示回退到上一个页面。
*   [pop](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navigation#pop11)：弹出路由栈栈顶元素，并触发onPop回调传入页面处理结果。

使用Navigation实现页面跳转，需要在module.json5[配置文件标签](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/module-configuration-file#配置文件标签)中添加routerMap配置，同时需要在resources/base/profile下添加[routerMap标签](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/module-configuration-file#routermap标签)配置文件。

#### 解决方案

在默认的返回按钮accessBackward中添加Web组件的onBackPressed判断，即判断当前Web页面内容是否可后退。如果可以后退，则调用Web的backward()返回上一个Web页面内容；如果不可后退，则调用Navigation的pop()返回Navigation的上一个页面。请参考[开发准备](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/graphics-accelerate-assetdownload-prepare)配置网络权限。

首页：

@Entry
@Component
struct NavigationExample {
  pageInfos: NavPathStack = new NavPathStack();
  isUseInterception: boolean = false;

  build() {
    Navigation(this.pageInfos) {
      Column() {
        Button('pageOne', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            this.pageInfos.pushPath({ name: 'pageOne' }); _// 将name指定的NavDestination页面信息入栈_
          });
      };
    }
    .title('Home');
  }
}

PageOne页面：

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

@Builder
export function PageOneBuilder() {
  PageOne();
}

@Component
export struct PageOne {
  pageInfos: NavPathStack = new NavPathStack();
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    NavDestination() {
      Column() {
     _   // 'www.xxx.com'更换为目标网址_
        Web({ src: 'www.xxx.com', controller: this.controller });
      }
      .width('100%')
      .height('100%');
    }
    .title('pageOne')
    .onBackPressed(() => {
      if (this.controller.accessBackward()) { _// 判断web页面是否可以后退_
        this.controller.backward(); _// web页面后退_
        return true;
      } else {
        this.pageInfos.pop();
        return true;
      }
    })
    .onReady((context: NavDestinationContext) => {
      this.pageInfos = context.pathStack;
    });
  }
}

router\_map.json文件配置如下：

{
  "routerMap": \[
    {
      "name": "pageOne",
      "pageSourceFile": "src/main/ets/pages/PageOne.ets",
      "buildFunction": "PageOneBuilder",
      "data": {}
    }
  \]
}

#### 常见FAQ

Q：弹窗如何拦截侧边返回？

A：通过配置[CustomDialogControllerOptions](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-methods-custom-dialog-box#customdialogcontrolleroptions对象说明)中的onWillDismiss参数进行拦截。