提示:目前API9、鸿蒙4.0的本地模拟器不支持交互,巨坑。参考踩坑链接
一、原生调用H5方法
在H5中定义一个方法,例如test方法,返回一个字符串"This value is from index.html",如下
<!-- index.html -->
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<body>
</body>
<script type="text/javascript">
function test() {
console.log('run javascript test')
return "This value is from index.html"
}
</script>
</html>
原生开发中,使用runJavaScript方法执行H5的方法
//执行js方法
runJavaScriptFunc() {
//注意执行H5方法前需要H5加载完成,在H5加载的onPageEnd方法中设置
if (!this.loadFinish) {
return
}
this.controller.runJavaScript('test()',(err,val) => {
if (err) {
console.log('run javascript err '+ JSON.stringify(err))
return
}
if (val) {
this.message = val
}
console.log('run javascript success '+ val)
})
}
这样,我们在原生开发中就执行了H5的test方法,并且拿到了test方法返回的字符串"This value is from index.html"
二、H5调用原生的方法
首先原生开发需要定义方法和调用对象,如下
testObj = {
test:(data) => {
this.message = '调用了当前方法'
console.log('javascript run test 调用了当前方法')
return 'ArkUI Web Component'
},
toString:() => {
console.log('Web Component toString')
}
}
定义好方法后,需要将方法注册到H5的控制器中
try {
//注册方法到H5的控制器
//参数1:传入调用方法的对象
//参数2:H5在使用该对象的名字
//参数3:方法列表(数组)
this.controller.registerJavaScriptProxy(this.testObj,'objName',['add','test','toString'])
//注册完需要刷新才能生效
this.controller.refresh()
} catch (err) {
console.log('run javascript register err '+ err)
}
H5开发就可以在需要的地方调用这些方法了,如下调用test方法
<!-- index.html -->
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<body>
<button style="width:200px;height:200px" type="button" onclick="htmlTest()">Click Me!</button>
<p id="demo"></p>
</body>
<script type="text/javascript">
function htmlTest() {
let str=objName.test();
document.getElementById("demo").innerHTML=str;
console.log('testObj.test result:'+ str)
}
</script>
</html>
三、ets文件的全部代码
import webview from '@ohos.web.webview'
@Entry
@Component
struct OfficialWebPage {
@State message: string = '执行H5的方法'
controller: WebviewController = new webview.WebviewController()
//web加载状态
loadFinish: boolean = false
@State buttonTitle: string = 'register javascript to Window'
//定义对象和方法供H5回调
testObj = {
test:(data) => {
this.message = '调用了当前方法'
console.log('run javascript 调用了当前方法')
return 'ArkUI Web Component'
},
toString:() => {
console.log('Web Component toString')
}
}
build() {
Column() {
Text(this.message)
.maxFontSize(50)
.minFontSize(20)
.fontWeight(FontWeight.Bold)
.onClick(() => {
//执行H5方法
this.runJavaScriptFunc()
// this.message = this.getWebUrl()
})
Button(this.buttonTitle)
.onClick(() => {
try {
//将原生方法注册到H5
this.controller.registerJavaScriptProxy(this.testObj,'objName',['add','test','toString'])
this.controller.refresh()
this.buttonTitle = 'had registered javascript'
} catch (err) {
console.log('run javascript register err '+ err)
}
})
//加载对应的H5
Web({src:$rawfile('index.html'),controller:this.controller})
.javaScriptAccess(true)
.backgroundColor(Color.Yellow)
.onPageEnd(val => { //加载完成
console.log('run javascript page end ')
this.loadFinish = true
})
}
.width('100%')
.height('100%')
}
//获取当前网页加载地址
getWebUrl(): string {
return this.controller.getUrl()
}
//执行js方法
runJavaScriptFunc() {
if (!this.loadFinish) {
return
}
this.controller.runJavaScript('test()',(err,val) => {
if (err) {
console.log('run javascript err '+ JSON.stringify(err))
return
}
if (val) {
this.message = val
}
console.log('run javascript success '+ val)
})
}
}
四、注意点
1、官方API的类名称有误,文档中用的web_webview,其实是webview。已经反馈给官方
2、开头提到的,API9、鸿蒙4.0本地模拟器不支持加载的webview用户交互