您现在的位置是:首页 >技术交流 >【鸿蒙】鸿蒙原生arkUI和H5交互网站首页技术交流
【鸿蒙】鸿蒙原生arkUI和H5交互
简介鸿蒙jsbridge[harmony]不存在
效果图
1、arkUI加载h5页面,设置 jsBridge,设置请求拦截器(onInterceptRequest)等
NavDestination(){
NavigationBar({ title: 'h5', rightTitle: '发数据给H5', rightCallBack: () => {
// 向h5发送数据
this.jsBridge.callback(1, 'Hello H5')
} })
Web({
src: $rawfile('index.html'),
controller: this.webController
})
.onPageBegin(() => {
this.jsBridge.initJsBridge()
})
// .onInterceptRequest((event) => {
// return interceptRequest(event)
// })
.javaScriptAccess(true)
.domStorageAccess(true)
.javaScriptProxy(this.jsBridge.javaScriptProxy)
.fileAccess(true)
.width('100%')
.height('100%')
.mixedMode(MixedMode.All)
.zoomAccess(false)
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST,
scrollBackward: NestedScrollMode.SELF_FIRST,
})
}.hideTitleBar(true)
1.0、封装的JsBridge
export class JsBridge {
controller: webview.WebviewController;
constructor(controller: webview.WebviewController) {
this.controller = controller;
}
/**
* 将 JavaScript 对象注window,并在window中调用函数。
*
* @returns javaScriptProxy.
*/
get javaScriptProxy(): JavaScriptItem {
let result: JavaScriptItem = {
object: {
call: this.call
},
name: 'JSBridgeHandle',
methodList: ['call'],
controller: this.controller
}
return result;
}
/**
* JsBridge初始化
*/
initJsBridge(): void {
this.controller.runJavaScript(code);
}
// 收到来自h5的数据
call = (func: string, params: string): void => {
let paramsObject: ParamsItem = JSON.parse(params)
let result: Promise<string> = new Promise((resolve) => resolve(''));
switch (func) {
case 'getH5Content':
result = this.openAlert(paramsObject as ParamsItem);
console.log('---', paramsObject)
break;
default:
break;
}
result.then((data: string) => {
this.callback(paramsObject?.callID, data);
})
}
/**
* 使用 runJavaScript 调用 WebView。
*/
callback = (id: number, data: string): void => {
this.controller.runJavaScript(`JSBridgeCallback('${id}', ${JSON.stringify(data)})`);
}
openAlert = (params: ParamsItem): Promise<string> => {
AlertDialog.show({ message: params.data.content })
return new Promise((resolve) => {
resolve('success');
})
}
}
1.0.0、其中code可以封装到constant/CodeConstant.ets目录,代码如下
export const code = `
// 定义一个对象,用于存储回调函数,键为调用ID
const JSBridgeMap = {};
// 初始化调用ID为0
let callID = 0;
/**
* JSBridge回调函数
* 当原生端调用此函数时执行
* @param {number} id - 调用ID,用于查找对应的回调函数
* @param {any} params - 原生端返回的参数
*/
function JSBridgeCallback (id, params) {
// 执行对应的回调函数,并传入参数
JSBridgeMap[id](params);
// 回调函数执行后,清除该回调函数
JSBridgeMap[id] = null;
delete JSBridgeMap[id];
}
// 定义一个对象,提供与原生端通信的方法
window.ohosCallNative = {
/**
* 调用原生端方法
* @param {string} method - 要调用的原生方法名
* @param {any} params - 传递给原生端的参数
* @param {Function} callback - 调用原生端方法后的回调函数,默认为空函数
*/
callNative(method, params, callback) {
// 生成唯一的调用ID
const id = callID++;
// 构造参数对象,包含调用ID和数据
const paramsObj = {
callID: id,
data: params || null
}
// 将回调函数存储在JSBridgeMap中,以便原生端调用
JSBridgeMap[id] = callback || (() => {});
// 调用原生端方法,并将参数对象序列化后传入
JSBridgeHandle.call(method, JSON.stringify(paramsObj));
}
}
`;
1.0.1、JavaScriptItem代码如下
/**
* 定义一个调用类型接口,用于规范调用函数的方式
* 这个接口主要用来统一调用方法的签名,确保调用的一致性和类型安全
*/
export interface callType {
/**
* 调用具体功能的方法
* @param func 要调用的函数名称
* @param params 调用函数时传递的参数
*/
call: (func: string, params: string) => void
}
/**
* 定义一个JavaScript项接口,用于描述JavaScript对象及其相关属性
* 这个接口主要用于在Web视图中与JavaScript交互时,提供一种类型安全的方式来组织和管理JavaScript对象
*/
export interface JavaScriptItem {
/**
* 包含调用方法的对象,通过这个对象可以调用JavaScript中的方法
*/
object: callType,
/**
* JavaScript对象的名称,用于标识该对象
*/
name: string,
/**
* 方法列表,列出了该对象中所有可调用的JavaScript方法名称
*/
methodList: Array<string>,
/**
* Web视图控制器,用于管理与JavaScript对象的交互
*/
controller: WebviewController
}
1.0.2、ParamsItem 代码如下
/**
* 定义参数项接口
* 用于描述API调用的参数格式
*/
export interface ParamsItem {
// 调用标识符,用于唯一标识一次调用
callID: number,
// 参数数据项,包含具体的参数信息
data: ParamsDataItem
}
export interface ParamsDataItem {
name?: string;
url?: string
content?: string;
}
export interface FileItem {
fileName: string;
filePath: string
}
2.0、H5示例代码
// index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>测试</title>
</script>
</head>
<body>
<header class="header">
</header>
<div class="box">
<div style="color: blue;" onclick="openHMAlert()">调用arkUI的弹框,并传递一个弹框内容“来自H5”</div>
<div id="concat_tip"></div>
</div>
</body>
<script type="text/javascript" charset="utf-8">
function openHMAlert() {
// 给原生发送数据
window.ohosCallNative.callNative('getH5Content', { content: '来自H5' });
}
// 接收来自原生的数据
JSBridgeCallback = (id, text) => {
document.getElementById('concat_tip').innerHTML = text
}
</script>
</html>
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。