事件

通用事件仅支持onAppearonDisAppearonBluronFocusonDragEndonDragEnteronDragStartonDragMoveonDragLeaveonDroponHoveronMouseonKeyEventonTouchonVisibleAreaChange

说明:

  • 该组件首批接口从API version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。

  • 示例效果请以真机运行为准,当前DevEco Studio预览器不支持。

onAlert

onAlert(callback: Callback<OnAlertEvent, boolean>)

网页触发alert()告警弹窗时触发回调。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnAlertEvent, boolean> 网页触发alert()告警弹窗时触发。
返回值boolean。当回调返回true时,应用可以调用自定义弹窗能力(包括确认和取消),并且需要根据用户的确认或取消操作调用JsResult通知Web组件最终确认结果。当回调返回false时,弹窗的处理结果会被视为取消。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  uiContext: UIContext = this.getUIContext();

  build() {
    Column() {
      Web({ src: $rawfile("index.html"), controller: this.controller })
        .onAlert((event) => {
          if (event) {
            console.log("event.url:" + event.url);
            console.log("event.message:" + event.message);
            this.uiContext.showAlertDialog({
              title: 'onAlert',
              message: 'text',
              primaryButton: {
                value: 'ok',
                action: () => {
                  event.result.handleConfirm();
                }
              },
              cancel: () => {
                event.result.handleCancel();
              }
            })
          }
          return true;
        })
    }
  }
}

加载的html文件。

<!--index.html-->
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
  <h1>WebView onAlert Demo</h1>
  <button onclick="myFunction()">Click here</button>
  <script>
    function myFunction() {
      alert("Hello World");
    }
  </script>
</body>
</html>

onBeforeUnload

onBeforeUnload(callback: Callback<OnBeforeUnloadEvent, boolean>)

即将完成页面刷新或关闭当前页面时触发此回调。

说明:

  • 如果当前Web组件没有得到焦点,刷新或关闭当前页面时onBeforeUnload不会触发。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnBeforeUnloadEvent, boolean> 即将完成页面刷新或关闭当前页面时触发。
返回值boolean。当回调返回true时,应用可以调用自定义弹窗能力(包括确认和取消),并且需要根据用户的确认或取消操作调用JsResult通知Web组件最终是否离开当前页面。当回调返回false时,函数中绘制的自定义弹窗无效。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  uiContext: UIContext = this.getUIContext();

  build() {
    Column() {
      Web({ src: $rawfile("index.html"), controller: this.controller })
        .onBeforeUnload((event) => {
          if (event) {
            console.log("event.url:" + event.url);
            console.log("event.message:" + event.message);
            this.uiContext.showAlertDialog({
              title: 'onBeforeUnload',
              message: 'text',
              primaryButton: {
                value: 'cancel',
                action: () => {
                  event.result.handleCancel();
                }
              },
              secondaryButton: {
                value: 'ok',
                action: () => {
                  event.result.handleConfirm();
                }
              },
              cancel: () => {
                event.result.handleCancel();
              }
            })
          }
          return true;
        })
    }
  }
}

加载的html文件。

<!--index.html-->
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body onbeforeunload="return myFunction()">
  <h1>WebView onBeforeUnload Demo</h1>
  <a href="https://www.example.com">Click here</a>
  <script>
    function myFunction() {
      return "onBeforeUnload Event";
    }
  </script>
</body>
</html>

onConfirm

onConfirm(callback: Callback<OnConfirmEvent, boolean>)

网页调用confirm()告警时触发此回调。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnConfirmEvent, boolean> 网页调用confirm()告警时触发。
返回值boolean。当回调返回true时,应用可以调用自定义弹窗能力(包括确认和取消),并且需要根据用户的确认或取消操作调用JsResult通知Web组件最终确认结果。当回调返回false时,弹窗的处理结果会被视为取消。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  uiContext: UIContext = this.getUIContext();

  build() {
    Column() {
      Web({ src: $rawfile("index.html"), controller: this.controller })
        .onConfirm((event) => {
          if (event) {
            console.log("event.url:" + event.url);
            console.log("event.message:" + event.message);
            this.uiContext.showAlertDialog({
              title: 'onConfirm',
              message: 'text',
              primaryButton: {
                value: 'cancel',
                action: () => {
                  event.result.handleCancel();
                }
              },
              secondaryButton: {
                value: 'ok',
                action: () => {
                  event.result.handleConfirm();
                }
              },
              cancel: () => {
                event.result.handleCancel();
              }
            })
          }
          return true;
        })
    }
  }
}

加载的html文件。

<!--index.html-->
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1.0">
</head>

<body>
  <h1>WebView onConfirm Demo</h1>
  <button onclick="myFunction()">Click here</button>
  <p id="demo"></p>
  <script>
    function myFunction() {
      let x;
      let r = confirm("click button!");
      if (r == true) {
        x = "ok";
      } else {
        x = "cancel";
      }
      document.getElementById("demo").innerHTML = x;
    }
  </script>
</body>
</html>

onPrompt9+

onPrompt(callback: Callback<OnPromptEvent, boolean>)

网页调用prompt()告警时触发此回调。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnPromptEvent, boolean> 网页调用prompt()告警时触发。
返回值boolean。当回调返回true时,应用可以调用自定义弹窗能力(包括确认、取消和输入),并且需要根据用户的确认或取消操作调用JsResult通知Web组件最终处理结果。当回调返回false时,弹窗的处理结果会被视为取消。

示例:

// xxx.ets
import { CustomContentDialog } from '@kit.ArkUI';
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  @State message: string = 'Hello World';
  @State title: string = 'Hello World';
  @State result: JsResult | null = null;
  promptResult: string = '';
  webviewController: webview.WebviewController = new webview.WebviewController();
  dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomContentDialog({
      primaryTitle: this.title,
      contentBuilder: () => {
        this.buildContent();
      },
      buttons: [
        {
          value: '取消',
          buttonStyle: ButtonStyleMode.TEXTUAL,
          action: () => {
            console.info('Callback when the button is clicked');
            this.result?.handleCancel()
          }
        },
        {
          value: '确认',
          buttonStyle: ButtonStyleMode.TEXTUAL,
          action: () => {
            this.result?.handlePromptConfirm(this.promptResult);
          }
        }
      ],
    }),
    onWillDismiss: () => {
      this.result?.handleCancel();
      this.dialogController.close();
    }
  });

  // 自定义弹出框的内容区
  @Builder
  buildContent(): void {
    Column() {
      Text(this.message)
      TextInput()
        .onChange((value) => {
          this.promptResult = value;
        })
        .defaultFocus(true)
    }
    .width('100%')
  }

  build() {
    Column() {
      Web({ src: $rawfile('index.html'), controller: this.webviewController })
        .onPrompt((event) => {
          if (event) {
            console.log("event.url:" + event.url);
            console.log("event.message:" + event.message);
            console.log("event.value:" + event.value);
            this.title = "来自" + event.url + "的消息";
            this.message = event.message;
            this.promptResult = event.value;
            this.result = event.result;
            this.dialogController.open();
          }
          return true;
        })
    }
  }
}

加载的html文件。

<!--index.html-->
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1.0">
</head>

<body>
  <h1>WebView onPrompt Demo</h1>
  <button onclick="myFunction()">Click here</button>
  <p id="demo"></p>
  <script>
    function myFunction() {
      let message = prompt("Message info", "Hello World");
      if (message != null && message != "") {
        document.getElementById("demo").innerHTML = message;
      }
    }
  </script>
</body>
</html>

onConsole

onConsole(callback: Callback<OnConsoleEvent, boolean>)

通知宿主应用JavaScript console消息。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnConsoleEvent, boolean> 网页收到JavaScript控制台消息时触发。
返回值boolean。当返回true时,该条消息将不会再打印至hilog日志,返回false时仍会打印至hilog日志。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Button('onconsole message')
        .onClick(() => {
          this.controller.runJavaScript('myFunction()');
        })
      Web({ src: $rawfile('index.html'), controller: this.controller })
        .onConsole((event) => {
          if (event) {
            console.log('getMessage:' + event.message.getMessage());
            console.log('getSourceId:' + event.message.getSourceId());
            console.log('getLineNumber:' + event.message.getLineNumber());
            console.log('getMessageLevel:' + event.message.getMessageLevel());
          }
          return false;
        })
    }
  }
}

加载的html文件。

<!-- index.html -->
<!DOCTYPE html>
<html>
<body>
<script>
    function myFunction() {
        console.log("onconsole printf");
    }
</script>
</body>
</html>

onDownloadStart

onDownloadStart(callback: Callback<OnDownloadStartEvent>)

通知主应用开始下载一个文件。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnDownloadStartEvent> 开始下载时触发。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onDownloadStart((event) => {
          if (event) {
            console.log('url:' + event.url)
            console.log('userAgent:' + event.userAgent)
            console.log('contentDisposition:' + event.contentDisposition)
            console.log('contentLength:' + event.contentLength)
            console.log('mimetype:' + event.mimetype)
          }
        })
    }
  }
}

onErrorReceive

onErrorReceive(callback: Callback<OnErrorReceiveEvent>)

网页加载遇到错误时触发该回调。主资源与子资源出错都会回调该接口,可以通过isMainFrame来判断是否是主资源报错。出于性能考虑,建议此回调中尽量执行简单逻辑。在无网络的情况下,触发此回调。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnErrorReceiveEvent> 网页收到 Web 资源加载错误时触发。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onErrorReceive((event) => {
          if (event) {
            console.log('getErrorInfo:' + event.error.getErrorInfo());
            console.log('getErrorCode:' + event.error.getErrorCode());
            console.log('url:' + event.request.getRequestUrl());
            console.log('isMainFrame:' + event.request.isMainFrame());
            console.log('isRedirect:' + event.request.isRedirect());
            console.log('isRequestGesture:' + event.request.isRequestGesture());
            console.log('getRequestHeader_headerKey:' + event.request.getRequestHeader().toString());
            let result = event.request.getRequestHeader();
            console.log('The request header result size is ' + result.length);
            for (let i of result) {
              console.log('The request header key is : ' + i.headerKey + ', value is : ' + i.headerValue);
            }
          }
        })
    }
  }
}

onHttpErrorReceive

onHttpErrorReceive(callback: Callback<OnHttpErrorReceiveEvent>)

网页加载资源遇到的HTTP错误(响应码>=400)时触发该回调。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnHttpErrorReceiveEvent> 网页收到加载资源返回HTTP码错误时触发。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onHttpErrorReceive((event) => {
          if (event) {
            console.log('url:' + event.request.getRequestUrl());
            console.log('isMainFrame:' + event.request.isMainFrame());
            console.log('isRedirect:' + event.request.isRedirect());
            console.log('isRequestGesture:' + event.request.isRequestGesture());
            console.log('getResponseData:' + event.response.getResponseData());
            console.log('getResponseEncoding:' + event.response.getResponseEncoding());
            console.log('getResponseMimeType:' + event.response.getResponseMimeType());
            console.log('getResponseCode:' + event.response.getResponseCode());
            console.log('getReasonMessage:' + event.response.getReasonMessage());
            let result = event.request.getRequestHeader();
            console.log('The request header result size is ' + result.length);
            for (let i of result) {
              console.log('The request header key is : ' + i.headerKey + ' , value is : ' + i.headerValue);
            }
            let resph = event.response.getResponseHeader();
            console.log('The response header result size is ' + resph.length);
            for (let i of resph) {
              console.log('The response header key is : ' + i.headerKey + ' , value is : ' + i.headerValue);
            }
          }
        })
    }
  }
}

onPageBegin

onPageBegin(callback: Callback<OnPageBeginEvent>)

网页开始加载时触发该回调,且只在主frame触发,iframe或者frameset的内容加载时不会触发此回调。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnPageBeginEvent> 网页加载开始时触发。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onPageBegin((event) => {
          if (event) {
            console.log('url:' + event.url);
          }
        })
    }
  }
}

onPageEnd

onPageEnd(callback: Callback<OnPageEndEvent>)

网页加载完成时触发该回调,且只在主frame触发,iframe或者frameset的内容加载时不会触发此回调。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnPageEndEvent> 网页加载结束时触发。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onPageEnd((event) => {
          if (event) {
            console.log('url:' + event.url);
          }
        })
    }
  }
}

onProgressChange

onProgressChange(callback: Callback<OnProgressChangeEvent>)

网页加载进度变化时触发该回调。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnProgressChangeEvent> 页面加载进度变化时触发的回调。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';
@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onProgressChange((event) => {
          if (event) {
            console.log('newProgress:' + event.newProgress);
          }
        })
    }
  }
}

onTitleReceive

onTitleReceive(callback: Callback<OnTitleReceiveEvent>)

当页面文档标题<title>元素发生变更时,触发回调。若当前页面未显示设置标题,ArkWeb将在加载完成前基于页面的URL生成标题并返回给应用。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnTitleReceiveEvent> 页面文档标题发生变更时触发

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onTitleReceive((event) => {
          if (event) {
            console.log('title:' + event.title);
          }
        })
    }
  }
}

onRefreshAccessedHistory

onRefreshAccessedHistory(callback: Callback<OnRefreshAccessedHistoryEvent>)

加载网页页面完成时触发该回调,用于应用更新其访问的历史链接。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnRefreshAccessedHistoryEvent> 在网页刷新访问历史记录时触发。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onRefreshAccessedHistory((event) => {
          if (event) {
            console.log('url:' + event.url + ' isReload:' + event.isRefreshed);
          }
        })
    }
  }
}

onRenderExited9+

onRenderExited(callback: Callback<OnRenderExitedEvent>)

应用渲染进程异常退出时触发该回调。

多个Web组件可能共享单个渲染进程,每个受影响的Web组件都会触发该回调。

应用处理该回调时,可以调用绑定的webviewController相关接口来恢复页面。例如refreshloadUrl等。

组件生命周期回调详情可参考Web组件的生命周期

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnRenderExitedEvent> 渲染过程退出时触发。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'chrome://crash/', controller: this.controller })
        .onRenderExited((event) => {
          if (event) {
            console.log('reason:' + event.renderExitReason);
          }
        })
    }
  }
}

onRenderProcessNotResponding12+

onRenderProcessNotResponding(callback: OnRenderProcessNotRespondingCallback)

渲染进程无响应时触发该回调函数。如果Web组件无法处理输入事件,或者无法在合理的时间范围内导航到新的URL,则认为网页进程无响应,并将触发该回调。

只要网页进程一直无响应,此回调仍可能会持续触发,直到网页进程再次响应,此时onRenderProcessResponding将会触发。

应用可以通过WebviewController接口terminateRenderProcess来终止关联的渲染进程,这可能会影响同一渲染进程的其他Web组件。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback OnRenderProcessNotRespondingCallback 渲染进程无响应时触发的回调。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onRenderProcessNotResponding((data) => {
          console.log("onRenderProcessNotResponding: [jsStack]= " + data.jsStack +
            ", [process]=" + data.pid + ", [reason]=" + data.reason);
        })
    }
  }
}

onRenderProcessResponding12+

onRenderProcessResponding(callback: OnRenderProcessRespondingCallback)

渲染进程由无响应状态变回正常运行状态时触发该回调函数,该回调表明该网页并非真正卡死。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback OnRenderProcessRespondingCallback 渲染进程由无响应状态变回正常运行状态时触发的回调。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onRenderProcessResponding(() => {
          console.log("onRenderProcessResponding again");
        })
    }
  }
}

onShowFileSelector9+

onShowFileSelector(callback: Callback<OnShowFileSelectorEvent, boolean>)

调用此函数以处理具有“文件”输入类型的HTML表单。如果不调用此函数或返回false,Web组件会提供默认的“选择文件”处理界面。如果返回true,应用可以自定义“选择文件”的响应行为。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnShowFileSelectorEvent, boolean> 用于通知Web组件文件选择的结果。
返回值boolean。当返回值为true时,用户可以调用系统提供的弹窗能力。当返回值为false时,函数中绘制的自定义弹窗无效。

示例:

  1. 拉起文件选择器。

    // xxx.ets
    import { webview } from '@kit.ArkWeb';
    import { picker } from '@kit.CoreFileKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    @Entry
    @Component
    struct WebComponent {
      controller: webview.WebviewController = new webview.WebviewController()
    
      build() {
        Column() {
          Web({ src: $rawfile('index.html'), controller: this.controller })
            .onShowFileSelector((event) => {
              console.log('MyFileUploader onShowFileSelector invoked')
              const documentSelectOptions = new picker.DocumentSelectOptions();
              let uri: string | null = null;
              const documentViewPicker = new picker.DocumentViewPicker();
              documentViewPicker.select(documentSelectOptions).then((documentSelectResult) => {
                uri = documentSelectResult[0];
                console.info('documentViewPicker.select to file succeed and uri is:' + uri);
                if (event) {
                  event.result.handleFileList([uri]);
                }
              }).catch((err: BusinessError) => {
                console.error(`Invoke documentViewPicker.select failed, code is ${err.code},  message is ${err.message}`);
              })
              return true;
            })
        }
      }
    }
    
  2. 拉起图库选择器。

    // xxx.ets
    import { webview } from '@kit.ArkWeb';
    import { picker } from '@kit.CoreFileKit';
    import { photoAccessHelper } from '@kit.MediaLibraryKit';
    
    @Entry
    @Component
    struct WebComponent {
      controller: webview.WebviewController = new webview.WebviewController()
    
      async selectFile(result: FileSelectorResult): Promise<void> {
        let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
        let photoPicker = new photoAccessHelper.PhotoViewPicker();
        // 过滤选择媒体文件类型为IMAGE
        photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE;
        // 设置最大选择数量
        photoSelectOptions.maxSelectNumber = 5;
        let chooseFile: photoAccessHelper.PhotoSelectResult = await photoPicker.select(photoSelectOptions);
        // 获取选择的文件列表
        result.handleFileList(chooseFile.photoUris);
      }
    
      build() {
        Column() {
          Web({ src: $rawfile('index.html'), controller: this.controller })
            .onShowFileSelector((event) => {
              if (event) {
                this.selectFile(event.result);
              }
              return true;
            })
        }
      }
    }
    
  3. 拉起相机选择器。

    // xxx.ets
    import { webview } from '@kit.ArkWeb';
    import { cameraPicker, camera } from '@kit.CameraKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    import { common } from '@kit.AbilityKit';
    
    async function openCamera(callback: Callback<string>, uiContext: UIContext) {
     let mContext = uiContext.getHostContext() as common.Context;
      try {
        let pickerProfile: cameraPicker.PickerProfile = {
          cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK
        };
        let pickerResult: cameraPicker.PickerResult = await cameraPicker.pick(mContext,
          [cameraPicker.PickerMediaType.PHOTO, cameraPicker.PickerMediaType.VIDEO], pickerProfile);
        callback(pickerResult.resultUri);
      } catch (error) {
        let err = error as BusinessError;
        console.error(`the pick call failed. error code: ${err.code}`);
      }
    }
    
    @Entry
    @Component
    struct WebComponent {
      controller: webview.WebviewController = new webview.WebviewController();
    
      build() {
        Column() {
          Web({ src: $rawfile('index.html'), controller: this.controller })
            .onShowFileSelector((event) => {
              openCamera((result) => {
                if (event) {
                  console.log('Title is ' + event.fileSelector.getTitle());
                  console.log('Mode is ' + event.fileSelector.getMode());
                  console.log('Accept types are ' + event.fileSelector.getAcceptType());
                  console.log('Capture is ' + event.fileSelector.isCapture());
                  console.log('Mime types are ' + event.fileSelector.getMimeTypes());
                  event.result.handleFileList([result]);
                }
              }, this.getUIContext())
              return true;
            })
        }
      }
    }
    

    加载的html文件。

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
      <form id="upload-form" enctype="multipart/form-data">
        <input type="file" id="upload" name="upload" accept="image/*, video/*"/>
        </form>
    </body>
    </html>
    

onResourceLoad9+

onResourceLoad(callback: Callback<OnResourceLoadEvent>)

通知Web组件所加载的资源文件url信息。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnResourceLoadEvent> 加载url时触发。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onResourceLoad((event) => {
          console.log('onResourceLoad: ' + event.url);
        })
    }
  }
}

onScaleChange9+

onScaleChange(callback: Callback<OnScaleChangeEvent>)

当页面显示比例发生变化时,触发该回调。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnScaleChangeEvent> 当页面显示比例发生变化时,触发该回调。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onScaleChange((event) => {
          console.log('onScaleChange changed from ' + event.oldScale + ' to ' + event.newScale);
        })
    }
  }
}

onInterceptRequest9+

onInterceptRequest(callback: Callback<OnInterceptRequestEvent, WebResourceResponse>)

当Web组件加载URL之前触发该回调,用于拦截URL并返回响应数据。onInterceptRequest可拦截所有跳转请求并返回响应数据,但无法访问POST请求体(Body)内容,且不支持分片缓冲(buffer)类型数据获取。此类场景需改用WebSchemeHandler实现,依据具体业务需求进行判断。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnInterceptRequestEvent, WebResourceResponse> 当Web组件加载url之前触发。
返回值WebResourceResponse。返回响应数据则按照响应数据加载,无响应数据则返回null表示按照原来的方式加载。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  responseWeb: WebResourceResponse = new WebResourceResponse();
  heads: Header[] = new Array();
  webData: string = "<!DOCTYPE html>\n" +
    "<html>\n" +
    "<head>\n" +
    "<title>intercept test</title>\n" +
    "</head>\n" +
    "<body>\n" +
    "<h1>intercept test</h1>\n" +
    "</body>\n" +
    "</html>";

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onInterceptRequest((event) => {
          if (event) {
            console.log('url:' + event.request.getRequestUrl());
          }
          let head1: Header = {
            headerKey: "Connection",
            headerValue: "keep-alive"
          }
          let head2: Header = {
            headerKey: "Cache-Control",
            headerValue: "no-cache"
          }
          // 将新元素追加到数组的末尾,并返回数组的新长度。
          let length = this.heads.push(head1);
          length = this.heads.push(head2);
          console.log('The response header result length is :' + length);
          const promise: Promise<String> = new Promise((resolve: Function, reject: Function) => {
            this.responseWeb.setResponseHeader(this.heads);
            this.responseWeb.setResponseData(this.webData);
            this.responseWeb.setResponseEncoding('utf-8');
            this.responseWeb.setResponseMimeType('text/html');
            this.responseWeb.setResponseCode(200);
            this.responseWeb.setReasonMessage('OK');
            resolve("success");
          })
          promise.then(() => {
            console.log("prepare response ready");
            this.responseWeb.setResponseIsReady(true);
          })
          this.responseWeb.setResponseIsReady(false);
          return this.responseWeb;
        })
    }
  }
}

onHttpAuthRequest9+

onHttpAuthRequest(callback: Callback<OnHttpAuthRequestEvent, boolean>)

通知收到http auth认证请求。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnHttpAuthRequestEvent, boolean> 当浏览器需要用户的凭据时触发。
返回值boolean。返回ture表示http auth认证成功,返回false表示http auth认证失败。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  uiContext: UIContext = this.getUIContext();
  httpAuth: boolean = false;

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onHttpAuthRequest((event) => {
          if (event) {
            this.uiContext.showAlertDialog({
              title: 'onHttpAuthRequest',
              message: 'text',
              primaryButton: {
                value: 'cancel',
                action: () => {
                  event.handler.cancel();
                }
              },
              secondaryButton: {
                value: 'ok',
                action: () => {
                  this.httpAuth = event.handler.isHttpAuthInfoSaved();
                  if (this.httpAuth == false) {
                    webview.WebDataBase.saveHttpAuthCredentials(
                      event.host,
                      event.realm,
                      "2222",
                      "2222"
                    )
                    event.handler.cancel();
                  }
                }
              },
              cancel: () => {
                event.handler.cancel();
              }
            })
          }
          return true;
        })
    }
  }
}

onSslErrorEventReceive9+

onSslErrorEventReceive(callback: Callback<OnSslErrorEventReceiveEvent>)

通知用户加载资源时发生SSL错误,只支持主资源。 如果需要支持子资源,请使用OnSslErrorEvent接口。

说明:

  • 主资源:浏览器加载网页的入口文件,通常是HTML文档。
  • 子资源:主资源中引用的依赖文件,由主资源解析过程中遇到特定标签时触发加载。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnSslErrorEventReceiveEvent> 当网页收到SSL错误时触发。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';
import { cert } from '@kit.DeviceCertificateKit';

function LogCertInfo(certChainData : Array<Uint8Array> | undefined) {
  if (!(certChainData instanceof Array)) {
    console.log('failed, cert chain data type is not array');
    return;
  }

  for (let i = 0; i < certChainData.length; i++) {
    let encodeBlobData: cert.EncodingBlob = {
      data: certChainData[i],
      encodingFormat: cert.EncodingFormat.FORMAT_DER
    }
    cert.createX509Cert(encodeBlobData, (error, x509Cert) => {
      if (error) {
        console.error('Index : ' + i + ',createX509Cert failed, errCode: ' + error.code + ', errMsg: ' + error.message);
      } else {
        console.log('createX509Cert success');
        console.log(ParseX509CertInfo(x509Cert));
      }
    });
  }
  return;
}

function Uint8ArrayToString(dataArray: Uint8Array) {
  let dataString = '';
  for (let i = 0; i < dataArray.length; i++) {
    dataString += String.fromCharCode(dataArray[i]);
  }
  return dataString;
}

function ParseX509CertInfo(x509Cert: cert.X509Cert) {
  let res: string = 'getCertificate success, '
    + 'issuer name = '
    + Uint8ArrayToString(x509Cert.getIssuerName().data) + ', subject name = '
    + Uint8ArrayToString(x509Cert.getSubjectName().data) + ', valid start = '
    + x509Cert.getNotBeforeTime()
    + ', valid end = ' + x509Cert.getNotAfterTime();
  return res;
}

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  uiContext: UIContext = this.getUIContext();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onSslErrorEventReceive((event) => {
          LogCertInfo(event.certChainData);
          this.uiContext.showAlertDialog({
            title: 'onSslErrorEventReceive',
            message: 'text',
            primaryButton: {
              value: 'confirm',
              action: () => {
                event.handler.handleConfirm();
              }
            },
            secondaryButton: {
              value: 'cancel',
              action: () => {
                event.handler.handleCancel();
              }
            },
            cancel: () => {
              event.handler.handleCancel();
            }
          })
        })
    }
  }
}

onSslErrorEvent12+

onSslErrorEvent(callback: OnSslErrorEventCallback)

通知用户加载资源(主资源+子资源)时发生SSL错误,如果只想处理主资源的SSL错误,请用isMainFrame字段进行区分。

说明:

  • 主资源:浏览器加载网页的入口文件,通常是HTML文档。
  • 子资源:主资源中引用的依赖文件,由主资源解析过程中遇到特定标签时触发加载。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback OnSslErrorEventCallback 通知用户加载资源时发生SSL错误。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  uiContext: UIContext = this.getUIContext();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onSslErrorEvent((event: SslErrorEvent) => {
          console.log("onSslErrorEvent url: " + event.url);
          console.log("onSslErrorEvent error: " + event.error);
          console.log("onSslErrorEvent originalUrl: " + event.originalUrl);
          console.log("onSslErrorEvent referrer: " + event.referrer);
          console.log("onSslErrorEvent isFatalError: " + event.isFatalError);
          console.log("onSslErrorEvent isMainFrame: " + event.isMainFrame);
          this.uiContext.showAlertDialog({
            title: 'onSslErrorEvent',
            message: 'text',
            primaryButton: {
              value: 'confirm',
              action: () => {
                event.handler.handleConfirm();
              }
            },
            secondaryButton: {
              value: 'cancel',
              action: () => {
                event.handler.handleCancel();
              }
            },
            cancel: () => {
              event.handler.handleCancel();
            }
          })
        })
    }
  }
}

onClientAuthenticationRequest9+

onClientAuthenticationRequest(callback: Callback<OnClientAuthenticationEvent>)

通知用户收到SSL客户端证书请求事件。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnClientAuthenticationEvent> 当需要用户提供的SSL客户端证书时触发的回调。

示例:

安装私有凭证以实现双向认证。

// xxx.ets
import { webview } from '@kit.ArkWeb';
import { common } from '@kit.AbilityKit';
import { certificateManager } from '@kit.DeviceCertificateKit';
import { promptAction } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct Index {
  controller: WebviewController = new webview.WebviewController();
  uiContext : UIContext = this.getUIContext();
  context : Context | undefined = this.uiContext.getHostContext() as common.UIAbilityContext;
  uri: string = ''

  aboutToAppear(): void {
    webview.WebviewController.setRenderProcessMode(webview.RenderProcessMode.MULTIPLE)
  }

  build() {
    Column() {
      Button("installPrivateCertificate").onClick(() => {
        if (!this.context) {
          return;
        }

        //注:badssl.com-client.p12需要替换为实际使用的证书文件
        let value: Uint8Array = this.context.resourceManager.getRawFileContentSync("badssl.com-client.p12");
        certificateManager.installPrivateCertificate(value, 'badssl.com', "1",
          async (err: BusinessError, data: certificateManager.CMResult) => {
            console.log(`installPrivateCertificate, uri==========${JSON.stringify(data.uri)}`)
            if (!err && data.uri) {
              this.uri = data.uri;
            }
          });
      })
      Button('加载需要客户端SSL证书的网站')
        .onClick(() => {
          this.controller.loadUrl("https://client.badssl.com")
        })
      Web({
        src: "https://www.bing.com/",
        controller: this.controller,
      }).domStorageAccess(true)
        .fileAccess(true)
        .onPageBegin(event => {
          console.log("extensions onpagebegin url " + event.url);
        })
        .onClientAuthenticationRequest((event) => {
          console.log("onClientAuthenticationRequest ");
          event.handler.confirm(this.uri);
          return true;
        })
        .onSslErrorEventReceive(e => {
          console.log(`onSslErrorEventReceive->${e.error.toString()}`);
        })
        .onErrorReceive((event) => {
          if (event) {
            this.getUIContext().getPromptAction().showToast({
              message: `ErrorCode: ${event.error.getErrorCode()}, ErrorInfo: ${event.error.getErrorInfo()}`,
              alignment: Alignment.Center
            })
            console.log('getErrorInfo:' + event.error.getErrorInfo());
            console.log('getErrorCode:' + event.error.getErrorCode());
            console.log('url:' + event.request.getRequestUrl());
          }
        })
        .onTitleReceive(event  => {
          console.log("title received " + event.title);
        })

    }
  }
}

对接证书管理,实现双向认证功能。

  1. 构造 GlobalContext 单例对象。

    // GlobalContext.ets
    export class GlobalContext {
      private constructor() {}
      private static instance: GlobalContext;
      private _objects = new Map<string, Object>();
    
      public static getContext(): GlobalContext {
        if (!GlobalContext.instance) {
          GlobalContext.instance = new GlobalContext();
        }
        return GlobalContext.instance;
      }
    
      getObject(value: string): Object | undefined {
        return this._objects.get(value);
      }
    
      setObject(key: string, objectClass: Object): void {
        this._objects.set(key, objectClass);
      }
    }
    
  2. 构造 CertManagerService 对象以对接证书管理。

```ts
// CertMgrService.ets
import { bundleManager, common, Want } from "@kit.AbilityKit";
import { BusinessError } from "@kit.BasicServicesKit";
import { GlobalContext } from './GlobalContext';

export default class CertManagerService {
  private static sInstance: CertManagerService;
  private authUri = "";
  private appUid = "";

  public static getInstance(): CertManagerService {
    if (CertManagerService.sInstance == null) {
      CertManagerService.sInstance = new CertManagerService();
    }
    return CertManagerService.sInstance;
  }

  async grantAppPm(): Promise<string> {
    let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_DEFAULT | bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION;
    // 注:com.example.myapplication需要写实际应用名称
    try {
      const data = await bundleManager.getBundleInfoForSelf(bundleFlags)
        .catch((err: BusinessError) => {
          console.error('getBundleInfoForSelf failed. Cause: %{public}s', err.message);
          return null;
        });
      this.appUid = data?.appInfo?.uid?.toString() ?? '';
      console.info('getBundleInfoForSelf successfully. Data: %{public}s', JSON.stringify(data));
    } catch (err) {
      let message = (err as BusinessError).message;
      console.error('getBundleInfoForSelf failed: %{public}s', message);
    }

    // 注:需要在MainAbility.ts文件的onCreate函数里添加GlobalContext.getContext().setObject("AbilityContext", this.context)
    let abilityContext = GlobalContext.getContext().getObject("AbilityContext") as common.UIAbilityContext;
    await abilityContext.startAbilityForResult(
      {
        bundleName: "com.ohos.certmanager",
        abilityName: "MainAbility",
        uri: "requestAuthorize",
        parameters: {
          appUid: this.appUid, // 传入申请应用的appUid
        }
      } as Want)
      .then((data: common.AbilityResult) => {
        if (!data.resultCode && data.want) {
          if (data.want.parameters) {
            this.authUri = data.want.parameters.authUri as string; // 授权成功后获取返回的authUri
          }
        }
      })
    return this.authUri;
  }
}
```
  1. 实现双向认证功能。
```ts
import { webview } from '@kit.ArkWeb';
import CertManagerService from './CertMgrService';
import { promptAction } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  controller: WebviewController = new webview.WebviewController();
  certManager = CertManagerService.getInstance();

  aboutToAppear(): void {
    webview.WebviewController.setRenderProcessMode(webview.RenderProcessMode.MULTIPLE)
  }

  build() {
    Column() {
      Button('加载需要客户端SSL证书的网站')
        .onClick(() => {
          this.controller.loadUrl("https://client.badssl.com")
        })
      Web({
        src: "https://www.bing.com/",
        controller: this.controller,
      }).domStorageAccess(true)
        .fileAccess(true)
        .onPageBegin(event => {
          console.log("extensions onpagebegin url " + event.url);
        })
        .onClientAuthenticationRequest((event) => {
          console.log("onClientAuthenticationRequest ");

          this.certManager.grantAppPm().then(result => {
            console.log(`grantAppPm, URI==========${result}`);
            event.handler.confirm(result);
          })
          return true;
        })
        .onSslErrorEventReceive(e => {
          console.log(`onSslErrorEventReceive->${e.error.toString()}`);
        })
        .onErrorReceive((event) => {
          if (event) {
            this.getUIContext().getPromptAction().showToast({
              message: `ErrorCode: ${event.error.getErrorCode()}, ErrorInfo: ${event.error.getErrorInfo()}`,
              alignment: Alignment.Center
            })
            console.log('getErrorInfo:' + event.error.getErrorInfo());
            console.log('getErrorCode:' + event.error.getErrorCode());
            console.log('url:' + event.request.getRequestUrl());
          }
        })
        .onTitleReceive(event  => {
          console.log("title received " + event.title);
        })

    }
  }
}
```

onPermissionRequest9+

onPermissionRequest(callback: Callback<OnPermissionRequestEvent>)

通知收到获取权限请求,需配置"ohos.permission.CAMERA"、"ohos.permission.MICROPHONE"权限。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnPermissionRequestEvent> 通知收到获取权限请求触发。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
import { abilityAccessCtrl } from '@kit.AbilityKit';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  uiContext: UIContext = this.getUIContext();

  aboutToAppear() {
    // 配置Web开启调试模式
    webview.WebviewController.setWebDebuggingAccess(true);
    let atManager = abilityAccessCtrl.createAtManager();
    atManager.requestPermissionsFromUser(this.uiContext.getHostContext(), ['ohos.permission.CAMERA', 'ohos.permission.MICROPHONE'])
      .then((data) => {
        console.info('data:' + JSON.stringify(data));
        console.info('data permissions:' + data.permissions);
        console.info('data authResults:' + data.authResults);
      }).catch((error: BusinessError) => {
      console.error(`Failed to request permissions from user. Code is ${error.code}, message is ${error.message}`);
    })
  }

  build() {
    Column() {
      Web({ src: $rawfile('index.html'), controller: this.controller })
        .onPermissionRequest((event) => {
          if (event) {
            this.uiContext.showAlertDialog({
              title: 'title',
              message: 'text',
              primaryButton: {
                value: 'deny',
                action: () => {
                  event.request.deny();
                }
              },
              secondaryButton: {
                value: 'onConfirm',
                action: () => {
                  event.request.grant(event.request.getAccessibleResource());
                }
              },
              cancel: () => {
                event.request.deny();
              }
            })
          }
        })
    }
  }
}

加载的html文件。

 <!-- index.html -->
 <!DOCTYPE html>
 <html>
 <head>
   <meta charset="UTF-8">
 </head>
 <body>
 <video id="video" width="500px" height="500px" autoplay></video>
 <canvas id="canvas" width="500px" height="500px"></canvas>
 <br>
 <input type="button" title="HTML5摄像头" value="开启摄像头" onclick="getMedia()"/>
 <script>
   function getMedia()
   {
     let constraints = {
       video: {width: 500, height: 500},
       audio: true
     };
     // 获取video摄像头区域
     let video = document.getElementById("video");
     // 返回的Promise对象
     let promise = navigator.mediaDevices.getUserMedia(constraints);
     // then()异步,调用MediaStream对象作为参数
     promise.then(function (MediaStream) {
       video.srcObject = MediaStream;
       video.play();
     }).catch(function(error) {
       console.error("Error accessing media devices.", error);
     });
   }
 </script>
 </body>
 </html>

onContextMenuShow9+

onContextMenuShow(callback: Callback<OnContextMenuShowEvent, boolean>)

长按特定元素(例如图片,链接)或鼠标右键,跳出菜单。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnContextMenuShowEvent, boolean> 调用时触发的回调,以允许自定义显示上下文菜单。
返回值boolean。返回true表示触发自定义菜单,返回false表示触发的自定义菜单无效。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';
import { pasteboard } from '@kit.BasicServicesKit';

const TAG = 'ContextMenu';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  private result: WebContextMenuResult | undefined = undefined;
  @State linkUrl: string = '';
  @State offsetX: number = 0;
  @State offsetY: number = 0;
  @State showMenu: boolean = false;
  uiContext: UIContext = this.getUIContext();

  @Builder
  // 构建自定义菜单及触发功能接口
  MenuBuilder() {
    // 以垂直列表形式显示的菜单。
    Menu() {
      // 展示菜单Menu中具体的item菜单项。
      MenuItem({
        content: '复制图片',
      })
        .width(100)
        .height(50)
        .onClick(() => {
          this.result?.copyImage();
          this.showMenu = false;
        })
      MenuItem({
        content: '剪切',
      })
        .width(100)
        .height(50)
        .onClick(() => {
          this.result?.cut();
          this.showMenu = false;
        })
      MenuItem({
        content: '复制',
      })
        .width(100)
        .height(50)
        .onClick(() => {
          this.result?.copy();
          this.showMenu = false;
        })
      MenuItem({
        content: '粘贴',
      })
        .width(100)
        .height(50)
        .onClick(() => {
          this.result?.paste();
          this.showMenu = false;
        })
      MenuItem({
        content: '复制链接',
      })
        .width(100)
        .height(50)
        .onClick(() => {
          let pasteData = pasteboard.createData('text/plain', this.linkUrl);
          pasteboard.getSystemPasteboard().setData(pasteData, (error) => {
            if (error) {
              return;
            }
          })
          this.showMenu = false;
        })
      MenuItem({
        content: '全选',
      })
        .width(100)
        .height(50)
        .onClick(() => {
          this.result?.selectAll();
          this.showMenu = false;
        })
    }
    .width(150)
    .height(300)
  }

  build() {
    Column() {
      Web({ src: $rawfile("index.html"), controller: this.controller })
        // 触发自定义弹窗
        .onContextMenuShow((event) => {
          if (event) {
            this.result = event.result
            console.info("x coord = " + event.param.x());
            console.info("link url = " + event.param.getLinkUrl());
            this.linkUrl = event.param.getLinkUrl();
          }
          console.info(TAG, `x: ${this.offsetX}, y: ${this.offsetY}`);
          this.showMenu = true;
          this.offsetX = 0;
          this.offsetY = Math.max(this.uiContext!.px2vp(event?.param.y() ?? 0) - 0, 0);
          return true;
        })
        .bindPopup(this.showMenu,
          {
            builder: this.MenuBuilder(),
            enableArrow: false,
            placement: Placement.LeftTop,
            offset: { x: this.offsetX, y: this.offsetY },
            mask: false,
            onStateChange: (e) => {
              if (!e.isVisible) {
                this.showMenu = false;
                this.result!.closeContextMenu();
              }
            }
          })
    }
  }
}

加载的html文件。

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<body>
  <h1>onContextMenuShow</h1>
  <a href="http://www.example.com" style="font-size:27px">链接www.example.com</a>
  // rawfile下放任意一张图片命名为example.png
  <div><img src="example.png"></div>
  <p>选中文字鼠标右键弹出菜单</p>
</body>
</html>

onContextMenuHide11+

onContextMenuHide(callback: OnContextMenuHideCallback)

长按特定元素(例如图片,链接)或鼠标右键,隐藏菜单。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback OnContextMenuHideCallback 菜单相关回调。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onContextMenuHide(() => {
          console.log("onContextMenuHide callback");
        })
    }
  }
}

onScroll9+

onScroll(callback: Callback<OnScrollEvent>)

通知网页全局滚动位置。

说明:

通知的是页面全局滚动位置,局部滚动位置的变化是无法触发此回调。

判断页面是否是全局滚动,在滚动前后打印window.pagYOffset或者window.pagXOffset。

如果是全局滚动,window.pagYOffset或者window.pagXOffset的值在滚动前后会有变化,反之没有变化。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnScrollEvent> 当页面滑动到指定位置时触发。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onScroll((event) => {
          console.info("x = " + event.xOffset);
          console.info("y = " + event.yOffset);
        })
    }
  }
}

onGeolocationShow

onGeolocationShow(callback: Callback<OnGeolocationShowEvent>)

通知用户收到地理位置信息获取请求。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnGeolocationShowEvent> 请求显示地理位置权限时触发。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  uiContext: UIContext = this.getUIContext();

  build() {
    Column() {
      Web({ src: $rawfile('index.html'), controller: this.controller })
        .geolocationAccess(true)
        .onGeolocationShow((event) => {
          if (event) {
            this.uiContext.showAlertDialog({
              title: 'title',
              message: 'text',
              confirm: {
                value: 'onConfirm',
                action: () => {
                  event.geolocation.invoke(event.origin, true, true);
                }
              },
              cancel: () => {
                event.geolocation.invoke(event.origin, false, true);
              }
            })
          }
        })
    }
  }
}

加载的html文件。

<!DOCTYPE html>
<html>
<body>
<p id="locationInfo">位置信息</p>
<button onclick="getLocation()">获取位置</button>
<script>
var locationInfo=document.getElementById("locationInfo");
function getLocation(){
  if (navigator.geolocation) {
    <!-- 前端页面访问设备地理位置 -->
    navigator.geolocation.getCurrentPosition(showPosition);
  }
}
function showPosition(position){
  locationInfo.innerHTML="Latitude: " + position.coords.latitude + "<br />Longitude: " + position.coords.longitude;
}
</script>
</body>
</html>

onGeolocationHide

onGeolocationHide(callback: () => void)

通知用户先前被调用onGeolocationShow时收到地理位置信息获取请求已被取消。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback () => void 地理位置信息获取请求已被取消的回调函数。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .geolocationAccess(true)
        .onGeolocationHide(() => {
          console.log("onGeolocationHide...");
        })
    }
  }
}

onFullScreenEnter9+

onFullScreenEnter(callback: OnFullScreenEnterCallback)

通知开发者Web组件进入全屏模式。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback OnFullScreenEnterCallback Web组件进入全屏时的回调信息。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  handler: FullScreenExitHandler | null = null;

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onFullScreenEnter((event) => {
          console.log("onFullScreenEnter videoWidth: " + event.videoWidth +
            ", videoHeight: " + event.videoHeight);
          // 应用可以通过 this.handler.exitFullScreen() 主动退出全屏。
          this.handler = event.handler;
        })
    }
  }
}

onFullScreenExit9+

onFullScreenExit(callback: () => void)

通知开发者Web组件退出全屏模式。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback () => void 退出全屏模式时的回调函数。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  handler: FullScreenExitHandler | null = null;

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onFullScreenExit(() => {
          console.log("onFullScreenExit...")
          if (this.handler) {
            this.handler.exitFullScreen();
          }
        })
        .onFullScreenEnter((event) => {
          this.handler = event.handler;
        })
    }
  }
}

onWindowNew9+

onWindowNew(callback: Callback<OnWindowNewEvent>)

使能multiWindowAccess情况下,通知用户新建窗口请求。 若不调用setWebController接口,会造成render进程阻塞。 如果没有创建新窗口,调用setWebController接口时设置成null,通知Web没有创建新窗口。

新窗口需避免直接覆盖在原Web组件上,且应与主页面以相同形式明确显示其URL(如地址栏)以防止用户混淆。若无法实现可信的URL可视化管理,则需考虑禁止创建新窗口。 需注意:新窗口请求来源无法可靠追溯,可能由第三方iframe发起,应用需默认采取沙箱隔离、限制权限等防御性措施以确保安全。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnWindowNewEvent> 网页要求用户创建窗口时触发的回调。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

// 在同一page页有两个Web组件。在WebComponent新开窗口时,会跳转到NewWebViewComp。
@CustomDialog
struct NewWebViewComp {
  controller?: CustomDialogController;
  webviewController1: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: "www.example.com", controller: this.webviewController1 })
        .javaScriptAccess(true)
        .multiWindowAccess(false)
        .onWindowExit(() => {
          console.info("NewWebViewComp onWindowExit");
          if (this.controller) {
            this.controller.close();
          }
        })
    }
  }
}

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  dialogController: CustomDialogController | null = null;

  build() {
    Column() {
      Web({ src: $rawfile("window.html"), controller: this.controller })
        .javaScriptAccess(true)
        // 需要使能multiWindowAccess
        .multiWindowAccess(true)
        .allowWindowOpenMethod(true)
        .onWindowNew((event) => {
          if (this.dialogController) {
            this.dialogController.close();
          }
          let popController: webview.WebviewController = new webview.WebviewController();
          this.dialogController = new CustomDialogController({
            builder: NewWebViewComp({ webviewController1: popController })
          })
          this.dialogController.open();
          // 将新窗口对应WebviewController返回给Web内核。
          // 若不调用event.handler.setWebController接口,会造成render进程阻塞。
          // 如果没有创建新窗口,调用event.handler.setWebController接口时设置成null,通知Web没有创建新窗口。
          event.handler.setWebController(popController);
        })
    }
  }
}
<!-- window.html页面代码 -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<a href="#" onclick="openNewWindow('https://www.example.com')">打开新页面</a>
<script type="text/javascript">
    function openNewWindow(url) {
      window.open(url, 'example');
      return false;
    }
</script>
</body>
</html>

onWindowExit9+

onWindowExit(callback: () => void)

通知用户窗口关闭请求。和onWindowNew一样,从安全角度讲,应用应该确保用户可以知道他们交互的页面已关闭。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback () => void 窗口请求关闭的回调函数。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onWindowExit(() => {
          console.log("onWindowExit...");
        })
    }
  }
}

onSearchResultReceive9+

onSearchResultReceive(callback: Callback<OnSearchResultReceiveEvent>)

回调通知调用方网页页内查找的结果。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnSearchResultReceiveEvent> 通知调用方网页页内查找的结果。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onSearchResultReceive(ret => {
          if (ret) {
            console.log("on search result receive:" + "[cur]" + ret.activeMatchOrdinal +
              "[total]" + ret.numberOfMatches + "[isDone]" + ret.isDoneCounting);
          }
        })
    }
  }
}

onDataResubmitted9+

onDataResubmitted(callback: Callback<OnDataResubmittedEvent>)

设置网页表单可以重新提交时触发的回调函数。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnDataResubmittedEvent> 网页表单可以重新提交时触发。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      // 在网页中点击提交之后,点击refresh按钮可以重新提交时的触发函数。
      Button('refresh')
        .onClick(() => {
          try {
            this.controller.refresh();
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
          }
        })
      Web({ src: $rawfile('index.html'), controller: this.controller })
        .onDataResubmitted((event) => {
          console.log('onDataResubmitted');
          event.handler.resend();
        })
    }
  }
}

加载的html文件。

 <!-- index.html -->
 <!DOCTYPE html>
 <html>
 <head>
   <meta charset="utf-8">
 </head>
 <body>
   <form action="http://httpbin.org/post" method="post">
     <input type="text" name="username">
     <input type="submit" name="提交">
   </form>
 </body>
 </html>

onPageVisible9+

onPageVisible(callback: Callback<OnPageVisibleEvent>)

设置旧页面不再呈现,新页面即将可见时触发的回调函数。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnPageVisibleEvent> 旧页面不再呈现,新页面即将可见时触发的回调函数。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onPageVisible((event) => {
          console.log('onPageVisible url:' + event.url);
        })
    }
  }
}

onInterceptKeyEvent9+

onInterceptKeyEvent(callback: (event: KeyEvent) => boolean)

设置键盘事件的回调函数,该回调在被Webview使用前触发。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback (event:KeyEvent) => boolean 触发的KeyEvent事件。
返回值为boolean类型,true表示将该KeyEvent传入Webview内核,false表示不将该KeyEvent传入ArkWeb内核。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onInterceptKeyEvent((event) => {
          if (event.keyCode == 2017 || event.keyCode == 2018) {
            console.info(`onInterceptKeyEvent get event.keyCode ${event.keyCode}`);
            return true;
          }
          return false;
        })
    }
  }
}

onTouchIconUrlReceived9+

onTouchIconUrlReceived(callback: Callback<OnTouchIconUrlReceivedEvent>)

设置接收到apple-touch-icon url地址时的回调函数。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnTouchIconUrlReceivedEvent> 接收到的apple-touch-icon url地址时触发。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.baidu.com', controller: this.controller })
        .onTouchIconUrlReceived((event) => {
          console.log('onTouchIconUrlReceived:' + JSON.stringify(event));
        })
    }
  }
}

onFaviconReceived9+

onFaviconReceived(callback: Callback<OnFaviconReceivedEvent>)

设置应用为当前页面接收到新的favicon时的回调函数。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnFaviconReceivedEvent> 当前页面接收到新的favicon时触发。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';
import { image } from '@kit.ImageKit';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  @State icon: image.PixelMap | undefined = undefined;

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onFaviconReceived((event) => {
          console.log('onFaviconReceived');
          this.icon = event.favicon;
        })
    }
  }
}

onAudioStateChanged10+

onAudioStateChanged(callback: Callback<OnAudioStateChangedEvent>)

设置网页上的音频播放状态发生改变时的回调函数。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnAudioStateChangedEvent> 网页上的音频播放状态发生改变时触发。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  @State playing: boolean = false;

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onAudioStateChanged(event => {
          this.playing = event.playing;
          console.debug('onAudioStateChanged playing: ' + this.playing);
        })
    }
  }
}

onFirstContentfulPaint10+

onFirstContentfulPaint(callback: Callback<OnFirstContentfulPaintEvent>)

设置网页首次内容绘制回调函数。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnFirstContentfulPaintEvent> 网页首次内容绘制回调函数。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onFirstContentfulPaint(event => {
          if (event) {
            console.log("onFirstContentfulPaint:" + "[navigationStartTick]:" +
            event.navigationStartTick + ", [firstContentfulPaintMs]:" +
            event.firstContentfulPaintMs);
          }
        })
    }
  }
}

onFirstMeaningfulPaint12+

onFirstMeaningfulPaint(callback: OnFirstMeaningfulPaintCallback)

设置网页绘制页面主要内容回调函数。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback OnFirstMeaningfulPaintCallback 网页绘制页面主要内容度量信息的回调。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onFirstMeaningfulPaint((details) => {
          console.log("onFirstMeaningfulPaint: [navigationStartTime]= " + details.navigationStartTime +
            ", [firstMeaningfulPaintTime]=" + details.firstMeaningfulPaintTime);
        })
    }
  }
}

onLargestContentfulPaint12+

onLargestContentfulPaint(callback: OnLargestContentfulPaintCallback)

设置网页绘制页面最大内容回调函数。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback OnLargestContentfulPaintCallback 网页绘制页面最大内容度量信息的回调。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onLargestContentfulPaint((details) => {
          console.log("onLargestContentfulPaint: [navigationStartTime]= " + details.navigationStartTime +
            ", [largestImagePaintTime]=" + details.largestImagePaintTime +
            ", [largestTextPaintTime]=" + details.largestTextPaintTime +
            ", [largestImageLoadStartTime]=" + details.largestImageLoadStartTime +
            ", [largestImageLoadEndTime]=" + details.largestImageLoadEndTime +
            ", [imageBPP]=" + details.imageBPP);
        })
    }
  }
}

onLoadIntercept10+

onLoadIntercept(callback: Callback<OnLoadInterceptEvent, boolean>)

当Web组件加载url之前触发该回调,用于判断是否阻止此次访问。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnLoadInterceptEvent, boolean> 截获资源加载时触发的回调。
返回值为boolean类型。返回true表示阻止此次加载,false表示允许此次加载。
默认值:false

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onLoadIntercept((event) => {
          console.log('url:' + event.data.getRequestUrl());
          console.log('isMainFrame:' + event.data.isMainFrame());
          console.log('isRedirect:' + event.data.isRedirect());
          console.log('isRequestGesture:' + event.data.isRequestGesture());
          return true;
        })
    }
  }
}

onRequestSelected

onRequestSelected(callback: () => void)

当Web组件获取焦点时触发回调。如果组件在未获焦状态下加载网页并成功获取焦点,将触发两次回调。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback () => void 当网页获取焦点时触发的回调。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onRequestSelected(() => {
          console.log('onRequestSelected');
        })
    }
  }
}

onScreenCaptureRequest10+

onScreenCaptureRequest(callback: Callback<OnScreenCaptureRequestEvent>)

通知收到屏幕捕获请求。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnScreenCaptureRequestEvent> 通知收到屏幕捕获请求。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  uiContext: UIContext = this.getUIContext();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onScreenCaptureRequest((event) => {
          if (event) {
            this.uiContext.showAlertDialog({
              title: 'title: ' + event.handler.getOrigin(),
              message: 'text',
              primaryButton: {
                value: 'deny',
                action: () => {
                  event.handler.deny();
                }
              },
              secondaryButton: {
                value: 'onConfirm',
                action: () => {
                  event.handler.grant({ captureMode: WebCaptureMode.HOME_SCREEN });
                }
              },
              cancel: () => {
                event.handler.deny();
              }
            })
          }
        })
    }
  }
}

onOverScroll10+

onOverScroll(callback: Callback<OnOverScrollEvent>)

该接口在网页过度滚动时触发,用于通知网页过度滚动的偏移量。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback Callback<OnOverScrollEvent> 网页过度滚动时触发。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onOverScroll((event) => {
          console.info("x = " + event.xOffset);
          console.info("y = " + event.yOffset);
        })
    }
  }
}

onControllerAttached10+

onControllerAttached(callback: () => void)

当Controller成功绑定到Web组件时触发该回调,并且该Controller必须为WebviewController,且禁止在该事件回调前调用Web组件相关的接口,否则会抛出js-error异常。 因该回调调用时网页还未加载,无法在回调中使用有关操作网页的接口,例如zoomInzoomOut等,可以使用loadUrlgetWebId等操作网页不相关的接口。

组件生命周期详情可参考Web组件的生命周期

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback () => void 当ArkWeb控制器初始化成功时触发的回调。

示例:

在该回调中使用loadUrl加载网页

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: '', controller: this.controller })
        .onControllerAttached(() => {
          this.controller.loadUrl($rawfile("index.html"));
        })
    }
  }
}

在该回调中使用getWebId

// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: $rawfile("index.html"), controller: this.controller })
        .onControllerAttached(() => {
          try {
            let id = this.controller.getWebId();
            console.log("id: " + id);
          } catch (error) {
            let code = (error as BusinessError).code;
            let message = (error as BusinessError).message;
            console.error(`ErrorCode: ${code},  Message: ${message}`);
          }
        })
    }
  }
}

加载的html文件。

<!-- index.html -->
<!DOCTYPE html>
<html>
    <body>
        <p>Hello World</p>
    </body>
</html>

onNavigationEntryCommitted11+

onNavigationEntryCommitted(callback: OnNavigationEntryCommittedCallback)

当网页跳转提交时触发该回调。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback OnNavigationEntryCommittedCallback 网页跳转提交时触发的回调。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onNavigationEntryCommitted((details) => {
          console.log("onNavigationEntryCommitted: [isMainFrame]= " + details.isMainFrame +
            ", [isSameDocument]=" + details.isSameDocument +
            ", [didReplaceEntry]=" + details.didReplaceEntry +
            ", [navigationType]=" + details.navigationType +
            ", [url]=" + details.url);
        })
    }
  }
}

onSafeBrowsingCheckResult11+

onSafeBrowsingCheckResult(callback: OnSafeBrowsingCheckResultCallback)

收到网站安全风险检查结果时触发的回调。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback OnSafeBrowsingCheckResultCallback 收到网站安全风险检查结果时触发的回调。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

export enum ThreatType {
  UNKNOWN = -1,
  THREAT_ILLEGAL = 0,
  THREAT_FRAUD = 1,
  THREAT_RISK = 2,
  THREAT_WARNING = 3,
}

export class OnSafeBrowsingCheckResultCallback {
  threatType: ThreatType = ThreatType.UNKNOWN;
}

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onSafeBrowsingCheckResult((callback) => {
          let jsonData = JSON.stringify(callback);
          let json: OnSafeBrowsingCheckResultCallback = JSON.parse(jsonData);
          console.log("onSafeBrowsingCheckResult: [threatType]= " + json.threatType);
        })
    }
  }
}

onNativeEmbedLifecycleChange11+

onNativeEmbedLifecycleChange(callback: (event: NativeEmbedDataInfo) => void)

当同层标签生命周期变化时触发该回调。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback (event: NativeEmbedDataInfo) => void 同层标签生命周期变化时触发该回调。

示例:

// EntryAbility.ets

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { webview } from '@kit.ArkWeb';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
    // API12新增:开启同层渲染BFCache开关
    let features = new webview.BackForwardCacheSupportedFeatures();
    features.nativeEmbed = true;
    features.mediaTakeOver = true;
    webview.WebviewController.enableBackForwardCache(features);
    webview.WebviewController.initializeWebEngine();
  }

  onDestroy(): void {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    // Main window is created, set main page for this ability
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
        return;
      }
      hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');
    });
  }

  onWindowStageDestroy(): void {
    // Main window is destroyed, release UI related resources
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
  }

  onForeground(): void {
    // Ability has brought to foreground
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
  }

  onBackground(): void {
    // Ability has back to background
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
  }
}
// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct WebComponent {
  @State embedStatus: string = '';
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      // 默认行为:点击按钮跳转页面,关闭index页面,使同层标签销毁。
      // API12新增:使能同层渲染所在的页面支持BFCache后,点击按钮跳转页面,关闭index页面,使同层标签进入BFCache。
      Button('Destroy')
      .onClick(() => {
        try {
          this.controller.loadUrl("www.example.com");
        } catch (error) {
          console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
        }
      })

      // API12新增:使能同层渲染所在的页面支持BFCache后,点击按钮返回页面,使同层标签离开BFCache。
      Button('backward')
      .onClick(() => {
        try {
          this.controller.backward();
        } catch (error) {
          console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
        }
      })

      // API12新增:使能同层渲染所在的页面支持BFCache后,点击按钮前进页面,使同层标签进入BFCache。
      Button('forward')
      .onClick(() => {
        try {
          this.controller.forward();
        } catch (error) {
          console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
        }
      })


      // API12新增同层标签进入离开BFCache状态:非http与https协议加载的网页,Web内核不支持进入BFCache;
      // 因此如果要测试ENTER_BFCACHE/LEAVE_BFCACHE状态,需要将index.html放到Web服务器上,使用http或者https协议加载,如:
      // Web({ src: "http://xxxx/index.html", controller: this.controller })
      Web({ src: $rawfile("index.html"), controller: this.controller })
        .enableNativeEmbedMode(true)
        .onNativeEmbedLifecycleChange((event) => {
          // 当加载页面中有同层标签会触发Create。
          if (event.status == NativeEmbedStatus.CREATE) {
            this.embedStatus = 'Create';
          }
          // 当页面中同层标签移动或者缩放时会触发Update。
          if (event.status == NativeEmbedStatus.UPDATE) {
            this.embedStatus = 'Update';
          }
          // 退出页面时会触发Destroy。
          if (event.status == NativeEmbedStatus.DESTROY) {
            this.embedStatus = 'Destroy';
          }
          // 同层标签所在的页面进入BFCache时,会触发Enter BFCache。
          if (event.status == NativeEmbedStatus.ENTER_BFCACHE) {
            this.embedStatus = 'Enter BFCache';
          }
          // 同层标签所在的页面离开BFCache时,会触发Leave BFCache。
          if (event.status == NativeEmbedStatus.LEAVE_BFCACHE) {
            this.embedStatus = 'Leave BFCache';
          }
          console.log("status = " + this.embedStatus);
          console.log("surfaceId = " + event.surfaceId);
          console.log("embedId = " + event.embedId);
          if (event.info) {
            console.log("id = " + event.info.id);
            console.log("type = " + event.info.type);
            console.log("src = " + event.info.src);
            console.log("width = " + event.info.width);
            console.log("height = " + event.info.height);
            console.log("url = " + event.info.url);
          }
        })
    }
  }
}

加载的html文件

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>同层渲染测试html</title>
    <meta name="viewport">
</head>
<body>
<div>
    <div id="bodyId">
        <embed id="nativeButton" type = "native/button" width="800" height="800" src="test? params1=1" style = "background-color:red"/>
    </div>
</div>
</body>
</html>

onNativeEmbedGestureEvent11+

onNativeEmbedGestureEvent(callback: (event: NativeEmbedTouchInfo) => void)

当手指触摸到同层标签时触发该回调。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback (event: NativeEmbedTouchInfo) => void 手指触摸到同层标签时触发该回调。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';
import { NodeController, BuilderNode, NodeRenderType, FrameNode, UIContext } from "@kit.ArkUI";

declare class Params {
  text: string;
  width: number;
  height: number;
}

declare class NodeControllerParams {
  surfaceId: string;
  renderType: NodeRenderType;
  width: number;
  height: number;
}

class MyNodeController extends NodeController {
  private rootNode: BuilderNode<[Params]> | undefined | null;
  private surfaceId_: string = "";
  private renderType_: NodeRenderType = NodeRenderType.RENDER_TYPE_DISPLAY;
  private width_: number = 0;
  private height_: number = 0;

  setRenderOption(params: NodeControllerParams) {
    this.surfaceId_ = params.surfaceId;
    this.renderType_ = params.renderType;
    this.width_ = params.width;
    this.height_ = params.height;
  }

  makeNode(uiContext: UIContext): FrameNode | null {
    this.rootNode = new BuilderNode(uiContext, { surfaceId: this.surfaceId_, type: this.renderType_ });
    this.rootNode.build(wrapBuilder(ButtonBuilder), { text: "myButton", width: this.width_, height: this.height_ });
    return this.rootNode.getFrameNode();
  }

  postEvent(event: TouchEvent | undefined): boolean {
    return this.rootNode?.postTouchEvent(event) as boolean;
  }
}

@Component
struct ButtonComponent {
  @Prop params: Params;
  @State bkColor: Color = Color.Red;

  build() {
    Column() {
      Button(this.params.text)
        .height(50)
        .width(200)
        .border({ width: 2, color: Color.Red })
        .backgroundColor(this.bkColor)

    }
    .width(this.params.width)
    .height(this.params.height)
  }
}

@Builder
function ButtonBuilder(params: Params) {
  ButtonComponent({ params: params })
    .backgroundColor(Color.Green)
}

@Entry
@Component
struct WebComponent {
  @State eventType: string = '';
  controller: webview.WebviewController = new webview.WebviewController();
  private nodeController: MyNodeController = new MyNodeController();
  uiContext: UIContext = this.getUIContext();

  build() {
    Column() {
      Stack() {
        NodeContainer(this.nodeController)
        Web({ src: $rawfile("index.html"), controller: this.controller })
          .enableNativeEmbedMode(true)
          .onNativeEmbedLifecycleChange((embed) => {
            if (embed.status == NativeEmbedStatus.CREATE) {
              this.nodeController.setRenderOption({
                surfaceId: embed.surfaceId as string,
                renderType: NodeRenderType.RENDER_TYPE_TEXTURE,
                width: this.uiContext!.px2vp(embed.info?.width),
                height: this.uiContext!.px2vp(embed.info?.height)
              });
              this.nodeController.rebuild();
            }
          })
          .onNativeEmbedGestureEvent((event) => {
            if (event && event.touchEvent) {
              if (event.touchEvent.type == TouchType.Down) {
                this.eventType = 'Down'
              }
              if (event.touchEvent.type == TouchType.Up) {
                this.eventType = 'Up'
              }
              if (event.touchEvent.type == TouchType.Move) {
                this.eventType = 'Move'
              }
              if (event.touchEvent.type == TouchType.Cancel) {
                this.eventType = 'Cancel'
              }
              let ret = this.nodeController.postEvent(event.touchEvent)
              if (event.result) {
                event.result.setGestureEventResult(ret, true);
              }
              console.log("embedId = " + event.embedId);
              console.log("touchType = " + this.eventType);
              console.log("x = " + event.touchEvent.touches[0].x);
              console.log("y = " + event.touchEvent.touches[0].y);
              console.log("Component globalPos:(" + event.touchEvent.target.area.globalPosition.x + "," + event.touchEvent.target.area.globalPosition.y + ")");
              console.log("width = " + event.touchEvent.target.area.width);
              console.log("height = " + event.touchEvent.target.area.height);
            }
          })
      }
    }
  }
}

加载的html文件

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>同层渲染测试html</title>
    <meta name="viewport">
</head>
<body>
<div>
    <div id="bodyId">
       <embed id="nativeButton" type = "native/button" width="800" height="800" src="test?params1=1" style = "background-color:red"/>
    </div>
</div>
</body>
</html>

onIntelligentTrackingPreventionResult12+

onIntelligentTrackingPreventionResult(callback: OnIntelligentTrackingPreventionCallback)

智能防跟踪功能使能时,当追踪者cookie被拦截时触发该回调。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback OnIntelligentTrackingPreventionCallback 智能防跟踪功能使能时,当追踪者cookie被拦截时触发的回调。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      // 需要打开智能防跟踪功能,才会触发onIntelligentTrackingPreventionResult回调
      Button('enableIntelligentTrackingPrevention')
        .onClick(() => {
          try {
            this.controller.enableIntelligentTrackingPrevention(true);
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
          }
        })
      Web({ src: 'www.example.com', controller: this.controller })
        .onIntelligentTrackingPreventionResult((details) => {
          console.log("onIntelligentTrackingPreventionResult: [websiteHost]= " + details.host +
            ", [trackerHost]=" + details.trackerHost);
        })
    }
  }
}

onOverrideUrlLoading12+

onOverrideUrlLoading(callback: OnOverrideUrlLoadingCallback)

当URL将要加载到当前Web中时触发该回调,让宿主应用程序有机会获得控制权,判断是否阻止Web加载URL。

说明:

  • POST请求不会触发该回调。
  • iframe加载HTTP(s)协议或about:blank时不会触发该回调,而加载非HTTP(s)协议的跳转会触发;调用loadUrl(url: string)主动触发的跳转不会触发该回调。
  • 不要在回调中使用相同的URL调用loadUrl(url: string)方法,然后返回true。 这样会不必要地中止当前加载,并用相同的URL发起一次新的加载。 要继续加载当前请求URL的正确做法是直接返回false,而不是调用loadUrl(url: string)。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback OnOverrideUrlLoadingCallback onOverrideUrlLoading的回调。
返回值boolean。返回ture表示中止加载URL,返回false表示继续在Web中加载URL

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: $rawfile("index.html"), controller: this.controller })
        .onOverrideUrlLoading((webResourceRequest: WebResourceRequest) => {
          if (webResourceRequest && webResourceRequest.getRequestUrl() == "about:blank") {
            return true;
          }
          return false;
        })
    }
  }
}

加载的html文件。

<!--index.html-->
<!DOCTYPE html>
<html>
<head>
  <title>测试网页</title>
</head>
<body>
  <h1>onOverrideUrlLoading Demo</h1>
  <a href="about:blank">Click here</a>// 访问about:blank。
</body>
</html>

onViewportFitChanged12+

onViewportFitChanged(callback: OnViewportFitChangedCallback)

网页meta中viewport-fit配置项更改时触发该回调,应用可在此回调中自适应布局视口。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback OnViewportFitChangedCallback 网页meta中viewport-fit配置项更改时触发的回调。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: $rawfile('index.html'), controller: this.controller })
        .onViewportFitChanged((data) => {
          let jsonData = JSON.stringify(data);
          let viewportFit: ViewportFit = JSON.parse(jsonData).viewportFit;
          if (viewportFit === ViewportFit.COVER) {
            // index.html网页支持沉浸式布局,可调用expandSafeArea调整web控件布局视口覆盖避让区域(状态栏或导航条)。
          } else if (viewportFit === ViewportFit.CONTAINS) {
            // index.html网页不支持沉浸式布局,可调用expandSafeArea调整web控件布局视口为安全区域。
          } else {
            // 默认值,可不作处理。
          }
        })
    }
  }
}

加载的html文件。

<!-- index.html -->
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,viewport-fit=cover">
  </head>
  <body>
    <div style="position: absolute; bottom: 0; margin-bottom: env(safe-area-inset-bottom)"></div>
  </body>
</html>

onInterceptKeyboardAttach12+

onInterceptKeyboardAttach(callback: WebKeyboardCallback)

网页中可编辑元素(如input标签)拉起软键盘之前会回调该接口,应用可以使用该接口拦截系统软键盘的弹出,配置应用定制的软键盘(应用根据该接口可以决定使用系统默认软键盘/定制enter键的系统软键盘/全部由应用自定义的软键盘)。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback WebKeyboardCallback 拦截网页拉起软键盘回调。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';
import { inputMethodEngine } from '@kit.IMEKit';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  webKeyboardController: WebKeyboardController = new WebKeyboardController()
  inputAttributeMap: Map<string, number> = new Map([
      ['UNSPECIFIED', inputMethodEngine.ENTER_KEY_TYPE_UNSPECIFIED],
      ['GO', inputMethodEngine.ENTER_KEY_TYPE_GO],
      ['SEARCH', inputMethodEngine.ENTER_KEY_TYPE_SEARCH],
      ['SEND', inputMethodEngine.ENTER_KEY_TYPE_SEND],
      ['NEXT', inputMethodEngine.ENTER_KEY_TYPE_NEXT],
      ['DONE', inputMethodEngine.ENTER_KEY_TYPE_DONE],
      ['PREVIOUS', inputMethodEngine.ENTER_KEY_TYPE_PREVIOUS]
    ])

    /**
     * 自定义键盘组件Builder
     */
    @Builder
    customKeyboardBuilder() {
        // 这里实现自定义键盘组件,对接WebKeyboardController实现输入、删除、关闭等操作。
      Row() {
        Text("完成")
          .fontSize(20)
          .fontColor(Color.Blue)
          .onClick(() => {
            this.webKeyboardController.close();
          })
        // 插入字符。
        Button("insertText").onClick(() => {
          this.webKeyboardController.insertText('insert ');
        }).margin({
          bottom: 200,
        })
        // 从后往前删除length参数指定长度的字符。
        Button("deleteForward").onClick(() => {
          this.webKeyboardController.deleteForward(1);
        }).margin({
          bottom: 200,
        })
        // 从前往后删除length参数指定长度的字符。
        Button("deleteBackward").onClick(() => {
          this.webKeyboardController.deleteBackward(1);
        }).margin({
          left: -220,
        })
        // 插入功能按键。
        Button("sendFunctionKey").onClick(() => {
          this.webKeyboardController.sendFunctionKey(6);
        })
      }
    }

  build() {
    Column() {
      Web({ src: $rawfile('index.html'), controller: this.controller })
      .onInterceptKeyboardAttach((KeyboardCallbackInfo) => {
        // option初始化,默认使用系统默认键盘
        let option: WebKeyboardOptions = {
          useSystemKeyboard: true,
        };
        if (!KeyboardCallbackInfo) {
          return option;
        }

        // 保存WebKeyboardController,使用自定义键盘时候,需要使用该handler控制输入、删除、软键盘关闭等行为
        this.webKeyboardController = KeyboardCallbackInfo.controller
        let attributes: Record<string, string> = KeyboardCallbackInfo.attributes
        // 遍历attributes
        let attributeKeys = Object.keys(attributes)
        for (let i = 0; i < attributeKeys.length; i++) {
          console.log('WebCustomKeyboard key = ' + attributeKeys[i] + ', value = ' + attributes[attributeKeys[i]])
        }

        if (attributes) {
          if (attributes['data-keyboard'] == 'customKeyboard') {
            // 根据html可编辑元素的属性,判断使用不同的软键盘,例如这里如果属性包含有data-keyboard,且值为customKeyboard,则使用自定义键盘
            console.log('WebCustomKeyboard use custom keyboard')
            option.useSystemKeyboard = false;
            // 设置自定义键盘builder
            option.customKeyboard = () => {
              this.customKeyboardBuilder()
            }
            return option;
          }

          if (attributes['keyboard-return'] != undefined) {
            // 根据html可编辑元素的属性,判断使用不同的软键盘,例如这里如果属性包含有keyboard-return,使用系统键盘,并且指定系统软键盘enterKey类型
            option.useSystemKeyboard = true;
            let enterKeyType: number | undefined = this.inputAttributeMap.get(attributes['keyboard-return'])
            if (enterKeyType != undefined) {
              option.enterKeyType = enterKeyType
            }
            return option;
          }
        }

        return option;
      })
    }
  }
}

加载的html文件。

<!-- index.html -->
  <!DOCTYPE html>
  <html>

  <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0">
  </head>

  <body>

  <p style="font-size:12px">input标签,原有默认行为:</p>
  <input type="text" style="width: 300px; height: 20px"><br>
  <hr style="height:2px;border-width:0;color:gray;background-color:gray">

  <p style="font-size:12px">input标签,系统键盘自定义enterKeyType属性 enter key UNSPECIFIED:</p>
  <input type="text" keyboard-return="UNSPECIFIED" style="width: 300px; height: 20px"><br>
  <hr style="height:2px;border-width:0;color:gray;background-color:gray">

  <p style="font-size:12px">input标签,系统键盘自定义enterKeyType属性 enter key GO:</p>
  <input type="text" keyboard-return="GO" style="width: 300px; height: 20px"><br>
  <hr style="height:2px;border-width:0;color:gray;background-color:gray">

  <p style="font-size:12px">input标签,系统键盘自定义enterKeyType属性 enter key SEARCH:</p>
  <input type="text" keyboard-return="SEARCH" style="width: 300px; height: 20px"><br>
  <hr style="height:2px;border-width:0;color:gray;background-color:gray">

  <p style="font-size:12px">input标签,系统键盘自定义enterKeyType属性 enter key SEND:</p>
  <input type="text" keyboard-return="SEND" style="width: 300px; height: 20px"><br>
  <hr style="height:2px;border-width:0;color:gray;background-color:gray">

  <p style="font-size:12px">input标签,系统键盘自定义enterKeyType属性 enter key NEXT:</p>
  <input type="text" keyboard-return="NEXT" style="width: 300px; height: 20px"><br>
  <hr style="height:2px;border-width:0;color:gray;background-color:gray">

  <p style="font-size:12px">input标签,系统键盘自定义enterKeyType属性 enter key DONE:</p>
  <input type="text" keyboard-return="DONE" style="width: 300px; height: 20px"><br>
  <hr style="height:2px;border-width:0;color:gray;background-color:gray">

  <p style="font-size:12px">input标签,系统键盘自定义enterKeyType属性 enter key PREVIOUS:</p>
  <input type="text" keyboard-return="PREVIOUS" style="width: 300px; height: 20px"><br>
  <hr style="height:2px;border-width:0;color:gray;background-color:gray">

  <p style="font-size:12px">input标签,应用自定义键盘:</p>
  <input type="text" data-keyboard="customKeyboard" style="width: 300px; height: 20px"><br>

  </body>

  </html>

onNativeEmbedVisibilityChange12+

onNativeEmbedVisibilityChange(callback: OnNativeEmbedVisibilityChangeCallback)

网页中同层标签(如<embed>标签或<embed>标签)在视口内的可见性发生变化时会触发该回调。同层标签默认不可见,如果首次进入页面可见则会上报,不可见则不会上报,当同层标签大小由非0值变为0 *0时,不会上报不可见,由0 *0变为非0值时会上报可见。同层标签全部不可见才算不可见,部分可见或全部可见算作可见。不支持由于CSS样式变化导致的同层标签可见状态变化上报,例如display、opacity和visibility等。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback OnNativeEmbedVisibilityChangeCallback 同层标签可见性变化时触发该回调。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';
import { NodeController, BuilderNode, NodeRenderType, FrameNode, UIContext } from "@kit.ArkUI";

declare class Params {
  text: string;
  width: number;
  height: number;
}

declare class NodeControllerParams {
  surfaceId: string;
  renderType: NodeRenderType;
  width: number;
  height: number;
}

class MyNodeController extends NodeController {
  private rootNode: BuilderNode<[Params]> | undefined | null;
  private surfaceId_: string = "";
  private renderType_: NodeRenderType = NodeRenderType.RENDER_TYPE_DISPLAY;
  private width_: number = 0;
  private height_: number = 0;

  setRenderOption(params: NodeControllerParams) {
    this.surfaceId_ = params.surfaceId;
    this.renderType_ = params.renderType;
    this.width_ = params.width;
    this.height_ = params.height;
  }

  makeNode(uiContext: UIContext): FrameNode | null {
    this.rootNode = new BuilderNode(uiContext, { surfaceId: this.surfaceId_, type: this.renderType_ });
    this.rootNode.build(wrapBuilder(ButtonBuilder), { text: "myButton", width: this.width_, height: this.height_ });
    return this.rootNode.getFrameNode();
  }

  postEvent(event: TouchEvent | undefined): boolean {
    return this.rootNode?.postTouchEvent(event) as boolean;
  }
}

@Component
struct ButtonComponent {
  @Prop params: Params;
  @State bkColor: Color = Color.Red;

  build() {
    Column() {
      Button(this.params.text)
        .height(50)
        .width(200)
        .border({ width: 2, color: Color.Red })
        .backgroundColor(this.bkColor)

    }
    .width(this.params.width)
    .height(this.params.height)
  }
}

@Builder
function ButtonBuilder(params: Params) {
  ButtonComponent({ params: params })
    .backgroundColor(Color.Green)
}

@Entry
@Component
struct WebComponent {
  @State embedVisibility: string = '';
  controller: webview.WebviewController = new webview.WebviewController();
  private nodeController: MyNodeController = new MyNodeController();
  uiContext: UIContext = this.getUIContext();

  build() {
    Column() {
      Stack() {
        NodeContainer(this.nodeController)
        Web({ src: $rawfile("index.html"), controller: this.controller })
          .enableNativeEmbedMode(true)
          .onNativeEmbedLifecycleChange((embed) => {
            if (embed.status == NativeEmbedStatus.CREATE) {
              this.nodeController.setRenderOption({
                surfaceId: embed.surfaceId as string,
                renderType: NodeRenderType.RENDER_TYPE_TEXTURE,
                width: this.uiContext!.px2vp(embed.info?.width),
                height: this.uiContext!.px2vp(embed.info?.height)
              });
              this.nodeController.rebuild();
            }
          })
          .onNativeEmbedVisibilityChange((embed) => {
            if (embed.visibility) {
              this.embedVisibility = 'Visible';
            } else {
              this.embedVisibility = 'Hidden';
            }
            console.log("embedId = " + embed.embedId);
            console.log("visibility = " + embed.visibility);
          })
      }
    }
  }
}

加载的html文件

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>同层渲染测试html</title>
    <meta name="viewport">
</head>
<body>
<div>
    <div id="bodyId">
        <embed id="nativeButton" type = "native/button" width="800" height="800" src="test?params1=1" style = "background-color:red"/>
    </div>
</div>
</body>
</html>

onSslErrorReceive(deprecated)

onSslErrorReceive(callback: (event?: { handler: Function, error: object }) => void)

通知用户加载资源时发生SSL错误。

说明:

从API version 8开始支持,从API version 9开始废弃。建议使用onSslErrorEventReceive9+替代。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback (event?: { handler: Function, error: object }) => void 当网页检测到SSL错误时触发的回调。

onFileSelectorShow(deprecated)

onFileSelectorShow(callback: (event?: { callback: Function, fileSelector: object }) => void)

调用此函数以处理具有“文件”输入类型的HTML表单,以响应用户按下的“选择文件”按钮。

说明:

从API version 8开始支持,从API version 9开始废弃。建议使用onShowFileSelector9+替代。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback (event?: { callback: Function, fileSelector: object }) => void 当触发文件选择器时需要执行的回调。

onUrlLoadIntercept(deprecated)

onUrlLoadIntercept(callback: (event?: { data:string | WebResourceRequest }) => boolean)

当Web组件加载url之前触发该回调,用于判断是否阻止此次访问。 从API version 10开始不再维护,建议使用onLoadIntercept10+代替。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
callback (event?: { data:string | WebResourceRequest }) => boolean url的相关信息。
返回值:boolean,true表示阻止此次加载,false表示允许此次加载。

示例:

// xxx.ets
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onUrlLoadIntercept((event) => {
          if (event) {
            console.log('onUrlLoadIntercept ' + event.data.toString());
          }
          return true
        })
    }
  }
}