HarmonyOS的web组件实现html和js的调用
在HarmonyOS开发中,想要加载网页,可以使用Web组件,Web组件的使用非常简单,只需要在Page目录下的ArkTS文件中创建一个Web组件,传入两个参数就可以了。其中src指定引用的网页路径,controller为组件的控制器,通过controller绑定Web组件,用于实现对Web组件的控制。
网页加载
@Entry@Componentstruct WebComponent { controller: WebController = new WebController(); build() { Column() { Web({ src: 'https://developer.harmonyos.com/', controller: this.controller }) } }}
Web组件可以访问在线网页,也可解析加载本地网页资源,如果访问在线网页,需要配置网络权限:
//module.json5{ "module" : { "requestPermissions":[ { "name": "ohos.permission.INTERNET" } ] }}
加载本地网页的话,把网页相关的资源存放到main/resources/rawfile下,然后通过$rawfile引用本地网页资源
@Entry@Componentstruct SecondPage { controller: WebController = new WebController(); build() { Column() { Web({ src: $rawfile('index.html'), controller: this.controller }) } }}
网页缩放
如果网页对我们移动端屏幕适配不佳的情况,用户可能想自己手动缩放网页,这个需求,我们可以设置web组件的属性来满足,对应属性事zoomAccess,默认是允许缩放。
Web({ src:'www.example.com', controller:this.controller }) .zoomAccess(true)
关于缩放,我们还可以设置每次缩放的倍数:
@Entry@Componentstruct WebComponent { controller: WebController = new WebController(); factor: number = 1.5; build() { Column() { Button('zoom') .onClick(() => { this.controller.zoom(this.factor); }) Web({ src: 'www.example.com', controller: this.controller }) } }}
如果我们要缩放文本内容,则通过使用textZoomAtio方法来实现效果:
Web({ src:'www.example.com', controller:this.controller }) .textZoomAtio(150)
处理js的confirm事件,onConfirm回调返回false,触发默认弹窗,返回true,系统调用系统弹窗能力。
如果我们希望加载的网页支持运行JavaScript的能力,则需要启用JavaScript功能,默认是允许JavaScript执行。
Web({ src:'https://www.example.com', controller:this.controller }) .javaScriptAccess(true)
Web组件调用JS里的方法
我们可以在Web组件onPageEnd事件中添加runJavaScript方法。事件是网页加载完成时的回调,runJavaScript方法可以执行HTML中的JavaScript脚本。
@Entry@Componentstruct WebComponent { controller: WebController = new WebController(); @State webResult: string = '' build() { Column() { Text(this.webResult).fontSize(20) Web({ src: $rawfile('index.html'), controller: this.controller }) .javaScriptAccess(true) .onPageEnd(e => { this.controller.runJavaScript({ script: 'test()', callback: (result: string)=> { this.webResult = result }}); }) } }}
function test() { return "This value is from index.html" }
JS调用Web组件方法
我们可以使用registerJavaScriptProxy将Web组件中的JavaScript对象到注入window对象中,这样网页中的JS就可以直接调用该对象了。需要注意的是,要想registerJavaScriptProxy方法生效,须调用refresh方法。下面的示例将ets文件中的对象testObj注入到了window对象中。
@Entry@Componentstruct WebComponent{ @State dataFromHtml: string = '' controller: WebController = new WebController() testObj = { test: (data) => { this.dataFromHtml = data return "ArkUI Web Component"; }, toString: () => { console.log('Web Component toString'); } } build() { Column() { Text(this.dataFromHtml).fontSize(20) Row() { Button('Register JavaScript To Window').onClick(() => { this.controller.registerJavaScriptProxy({ object: this.testObj, name: "objName", methodList: ["test", "toString"], }); this.controller.refresh(); }) } Web({ src: $rawfile('index.html'), controller: this.controller }) .javaScriptAccess(true) } }}
其中object表示参与注册的对象,name表示注册对象的名称为objName,与window中调用的对象名一致;methodList表示参与注册的应用侧JavaScript对象的方法,包含test、toString两个方法。在HTML中使用的时候直接使用objName调用methodList里面对应的方法即可,示例如下:
function htmlTest() { str = objName.test("param from Html"); }