一、应用侧调用前端页面函数
应用侧可以通过runJavaScript()方法调用前端页面的JavaScript相关函数。在下面的示例中,点击应用侧的"runJavaScript"按钮时,来触发前端页面的htmlTest()方法。
- 前端页面代码。
<!--` `index.html` `-->`
`<!DOCTYPE` `html>`
`<html>`
`<body>`
`<script>`
`function` `htmlTest()` `{`
`console.info('JavaScript Hello World! ');`
`}`
`</script>`
`</body>`
`</html>`
`
应用侧代码。
//` `xxx.ets`
`import` `web_webview` `from` `'@ohos.web.webview';`
`@Entry`
`@Component`
`struct` `WebComponent` `{`
`webviewController:` `web_webview.WebviewController` `=` `new` `web_webview.WebviewController();`
`build()` `{`
`Column()` `{`
`Web({` `src: $rawfile('index.html'),` `controller:` `this.webviewController})`
`Button('runJavaScript')`
`.onClick(()` `=>` `{`
`this.webviewController.runJavaScript('htmlTest()');`
`})`
`}`
`}`
`}`
`
二、前端页面调用应用侧函数
开发者使用Web组件将应用侧代码注册到前端页面中,注册完成之后,前端页面中使用注册的对象名称就可以调用应用侧的函数,实现在前端页面中调用应用侧方法。
注册应用侧代码有两种方式,一种在Web组件初始化使用调用,使用javaScriptProxy()接口。另外一种在Web组件初始化完成后调用,使用registerJavaScriptProxy()接口。
在下面的示例中,将test()方法注册在前端页面中, 该函数可以在前端页面触发运行。
- javaScriptProxy()接口使用示例如下。
//` `xxx.ets`
`import` `web_webview` `from` `'@ohos.web.webview';`
`@Entry`
`@Component`
`struct` `WebComponent` `{`
`webviewController:` `web_webview.WebviewController` `=` `new` `web_webview.WebviewController();`
`// 声明需要注册的对象`
`testObj` `=` `{`
`test:` `()` `=>` `{`
`return` `'ArkTS Hello World!';`
`}`
`}`
`build()` `{`
`Column()` `{`
`//` `web组件加载本地index.html页面`
`Web({` `src: $rawfile('index.html'),` `controller:` `this.webviewController})`
`// 将对象注入到web端`
`.javaScriptProxy({`
`object:` `this.testObj,`
`name:` `"testObjName",`
`methodList:` `["test"],`
`controller:` `this.webviewController`
`})`
`}`
`}`
`}`
`
- 应用侧使用registerJavaScriptProxy()接口注册。
//` `xxx.ets`
`import` `web_webview` `from` `'@ohos.web.webview';`
`@Entry`
`@Component`
`struct` `Index` `{`
`webviewController:` `web_webview.WebviewController` `=` `new` `web_webview.WebviewController();`
`testObj` `=` `{`
`test:` `(data)` `=>` `{`
`return` `"ArkUI Web Component";`
`},`
`toString:` `()` `=>` `{`
`console.info('Web Component toString');`
`}`
`}`
`build()` `{`
`Column()` `{`
`Button('refresh')`
`.onClick(()` `=>` `{`
`try` `{`
`this.webviewController.refresh();`
`}` `catch` `(error)` `{`
`console.error(`Errorcode: ${error.code},` `Message: ${error.message}`);`
`}`
`})`
`Button('Register JavaScript To Window')`
`.onClick(()` `=>` `{`
`try` `{`
`this.webviewController.registerJavaScriptProxy(this.testObj,` `"objName",` `["test",` `"toString"]);`
`}` `catch` `(error)` `{`
`console.error(`Errorcode: ${error.code},` `Message: ${error.message}`);`
`}`
`})`
`Web({` `src: $rawfile('index.html'),` `controller:` `this.webviewController` `})`
`}`
`}`
`}`
`
说明
使用registerJavaScriptProxy()接口注册方法时,注册后需调用refresh()接口生效。
- index.html前端页面触发应用侧代码。
<!--` `index.html` `-->`
`<!DOCTYPE` `html>`
`<html>`
`<body>`
`<button` `type="button"` `onclick="callArkTS()">Click` `Me!</button>`
`<p` `id="demo"></p>`
`<script>`
`function` `callArkTS()` `{`
`let` `str` `=` `objName.test();`
`document.getElementById("demo").innerHTML` `=` `str;`
`console.info('ArkTS Hello World! :'` `+` `str);`
`}`
`</script>`
`</body>`
`</html>`
`
三、建立应用侧与前端页面数据通道
前端页面和应用侧之间可以用createWebMessagePorts()接口创建消息端口来实现两端的通信。
在下面的示例中,应用侧页面中通过createWebMessagePorts方法创建消息端口,再把其中一个端口通过postMessage()接口发送到前端页面,便可以在前端页面和应用侧之间互相发送消息。
- 应用侧代码。
//` `xxx.ets`
`import` `web_webview` `from` `'@ohos.web.webview';`
`@Entry`
`@Component`
`struct` `WebComponent` `{`
`controller:` `web_webview.WebviewController` `=` `new` `web_webview.WebviewController();`
`ports:` `web_webview.WebMessagePort[];`
` @State` `sendFromEts:` `string` `=` `'Send this message from ets to HTML';`
` @State` `receivedFromHtml:` `string` `=` `'Display received message send from HTML';`
`build()` `{`
`Column()` `{`
`// 展示接收到的来自HTML的内容`
`Text(this.receivedFromHtml)`
`// 输入框的内容发送到html`
`TextInput({placeholder:` `'Send this message from ets to HTML'})`
`.onChange((value:` `string)` `=>` `{`
`this.sendFromEts` `=` `value;`
`})`
`Button('postMessage')`
`.onClick(()` `=>` `{`
`try` `{`
`//` `1、创建两个消息端口。`
`this.ports` `=` `this.controller.createWebMessagePorts();`
`//` `2、在应用侧的消息端口(如端口1)上注册回调事件。`
`this.ports[1].onMessageEvent((result:` `web_webview.WebMessage)` `=>` `{`
`let` `msg` `=` `'Got msg from HTML:';`
`if` `(typeof(result)` `===` `'string')` `{`
`console.info(`received` `string` `message` `from` `html5,` `string` `is: ${result}`);`
`msg` `=` `msg` `+` `result;`
`}` `else` `if` `(typeof(result)` `===` `'object')` `{`
`if` `(result` `instanceof` `ArrayBuffer)` `{`
`console.info(`received` `arraybuffer` `from` `html5,` `length` `is: ${result.byteLength}`);`
`msg` `=` `msg` `+` `'lenght is '` `+` `result.byteLength;`
`}` `else` `{`
`console.info('not support');`
`}`
`}` `else` `{`
`console.info('not support');`
`}`
`this.receivedFromHtml` `=` `msg;`
`})`
`//` `3、将另一个消息端口(如端口0)发送到HTML侧,由HTML侧保存并使用。`
`this.controller.postMessage('__init_port__',` `[this.ports[0]],` `'*');`
`}` `catch` `(error)` `{`
`console.error(`ErrorCode: ${error.code},` `Message: ${error.message}`);`
`}`
`})`
`//` `4、使用应用侧的端口给另一个已经发送到html的端口发送消息。`
`Button('SendDataToHTML')`
`.onClick(()` `=>` `{`
`try` `{`
`if` `(this.ports` `&&` `this.ports[1])` `{`
`this.ports[1].postMessageEvent(this.sendFromEts);`
`}` `else` `{`
`console.error(`ports` `is` `null,` `Please` `initialize` `first`);`
`}`
`}` `catch` `(error)` `{`
`console.error(`ErrorCode: ${error.code},` `Message: ${error.message}`);`
`}`
`})`
`Web({` `src: $rawfile('xxx.html'),` `controller:` `this.controller` `})`
`}`
`}`
`}`
`
- 前端页面代码。
<!--xxx.html-->`
`<!DOCTYPE` `html>`
`<html>`
`<head>`
`<meta` `name="viewport"` `content="width=device-width, initial-scale=1.0">`
`<title>WebView` `Message` `Port` `Demo</title>`
`</head>`
`<body>`
`<h1>WebView` `Message` `Port` `Demo</h1>`
`<div>`
`<input` `type="button"` `value="SendToEts"` `onclick="PostMsgToEts(msgFromJS.value);"/><br/>`
`<input` `id="msgFromJS"` `type="text"` `value="send this message from HTML to ets"/><br/>`
`</div>`
`<p` `class="output">display` `received` `message` `send` `from` `ets</p>`
`</body>`
`<script>`
`var` `h5Port;`
`var` `output` `=` `document.querySelector('.output');`
`window.addEventListener('message',` `function` `(event)` `{`
`if` `(event.data` `===` `'__init_port__')` `{`
`if` `(event.ports[0]` `!==` `null)` `{`
`h5Port` `=` `event.ports[0];` `//` `1. 保存从ets侧发送过来的端口`
`h5Port.onmessage` `=` `function` `(event)` `{`
`//` `2. 接收ets侧发送过来的消息.`
`var` `msg` `=` `'Got message from ets:';`
`var` `result` `=` `event.data;`
`if` `(typeof(result)` `===` `'string')` `{`
`console.info(`received` `string` `message` `from` `html5,` `string` `is: ${result}`);`
`msg` `=` `msg` `+` `result;`
`}` `else` `if` `(typeof(result)` `===` `'object')` `{`
`if` `(result` `instanceof` `ArrayBuffer)` `{`
`console.info(`received` `arraybuffer` `from` `html5,` `length` `is: ${result.byteLength}`);`
`msg` `=` `msg` `+` `'lenght is '` `+` `result.byteLength;`
`}` `else` `{`
`console.info('not support');`
`}`
`}` `else` `{`
`console.info('not support');`
`}`
`output.innerHTML` `=` `msg;`
`}`
`}`
`}`
`})`
`//` `3. 使用h5Port往ets侧发送消息.`
`function` `PostMsgToEts(data)` `{`
`if` `(h5Port)` `{`
`h5Port.postMessage(data);`
`}` `else` `{`
`console.error('h5Port is null, Please initialize first');`
`}`
`}`
`</script>`
`</html>`
`