🚀前言
前端函式和應用側函式相互呼叫是指前端頁面中的JavaScript函式和應用程式側的函式之間進行相互呼叫。
在前端開發中,常常會使用JavaScript函式來處理使用者的互動事件和操作。這些函式可以在前端頁面中定義,例如透過事件監聽器或者按鈕點選事件來觸發函式的執行。這些前端函式可以使用DOM操作、修改頁面樣式以及向後端傳送請求等。
而應用側函式是指在應用程式中定義的函式,例如後端伺服器端指令碼、資料庫操作函式等。這些函式通常用於處理業務邏輯、資料處理、資料庫操作等。
前端函式和應用側函式可以透過各種方式進行相互呼叫。例如,前端函式可以透過AJAX請求將資料傳送到應用側函式進行處理,應用側函式可以返回處理結果給前端函式。另外,前端函式也可以透過呼叫後端API介面來執行應用側函式。
不過HarmonyOS的Web元件前端函式和應用側函式相互呼叫是已經封裝好的。
🚀一、呼叫前端頁面函式
🔎1.應用側呼叫前端頁面函式
🦋1.1 前端頁面
<!-- index.html -->
<!DOCTYPE html>
<html>
<body>
<h1>執行JavaScript</h1>
<p id="locationInfo">位置資訊</p>
<script>
var locationInfo=document.getElementById("locationInfo");
function htmlTest() {
locationInfo.innerHTML='JavaScript Hello World! '
}
</script>
</body>
</html>
🦋1.2 應用側
// 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('local.html'), controller: this.webviewController})
Button('runJavaScript')
.onClick(() => {
this.webviewController.runJavaScript('htmlTest()');
})
}
}
}
🔎2.前端頁面呼叫應用側函式
🦋2.1 前端頁面
<!-- index.html -->
<!DOCTYPE html>
<html>
<body>
<button type="button" onclick="callArkTS()">Click Me!</button>
<p id="demo"></p>
<script>
function callArkTS() {
let str = testObjName.test();
document.getElementById("demo").innerHTML = str;
console.info('ArkTS Hello World! :' + str);
}
</script>
</body>
</html>
🦋2.2 應用側
☀️2.2.1 初始化時呼叫
// xxx.ets
import web_webview from '@ohos.web.webview';
class testClass {
constructor() {
}
test(): string {
return 'ArkTS Hello World!';
}
}
@Entry
@Component
struct WebComponent {
webviewController: web_webview.WebviewController = new web_webview.WebviewController();
// 宣告需要註冊的物件
@State testObj: testClass = new testClass();
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
})
}
}
}
☀️2.2.2 初始化後呼叫
// xxx.ets
import web_webview from '@ohos.web.webview';
// @ts-ignore
import business_error from '@ohos.base';
class testClass {
constructor() {
}
test(): string {
return "ArkUI Web Component";
}
toString(): void {
console.log('Web Component toString');
}
}
@Entry
@Component
struct Index {
webviewController: web_webview.WebviewController = new web_webview.WebviewController();
@State testObj: testClass = new testClass();
build() {
Column() {
Button('refresh')
.onClick(() => {
try {
this.webviewController.refresh();
} catch (error) {
let e: business_error.BusinessError = error as business_error.BusinessError;
console.error(`ErrorCode: ${e.code}, Message: ${e.message}`);
}
})
Button('Register JavaScript To Window')
.onClick(() => {
try {
this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "test"]);
} catch (error) {
let e: business_error.BusinessError = error as business_error.BusinessError;
console.error(`ErrorCode: ${e.code}, Message: ${e.message}`);
}
})
Web({ src: $rawfile('local.html'), controller: this.webviewController })
}
}
}
🔎3.建立應用側與前端頁面資料通道
🦋3.1 前端頁面
<!--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>
🦋3.2 應用側
// 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 })
}
}
}
🚀寫在最後
- 如果你覺得這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:
- 點贊,轉發,有你們的 『點贊和評論』,才是我創造的動力。
- 關注小編,同時可以期待後續文章ing🚀,不定期分享原創知識。
- 更多鴻蒙最新技術知識點,請關注作者部落格:https://t.doruo.cn/14DjR1rEY