文章末尾含:Web组件抽奖案例(ArkTS)-示例源码下载
相信大家都遇到过这样的场景,有时候我们点击应用的页面,会跳转到一个类似浏览器加载的页面,加载完成后,才显示这个页面的具体内容,这个加载和显示网页的过程通常都是浏览器的任务。
ArkUI
为我们提供了Web
组件来加载网页,借助它我们就相当于在自己的应用程序里嵌入一个浏览器,从而非常轻松地展示各种各样的网页。
Web
组件的使用非常简单,只需要在Page
目录下的ArkTS
文件中创建一个Web
组件,传入两个参数就可以了。其中src
指定引用的网页路径,controller
为组件的控制器,通过controller
绑定Web
组件,用于实现对Web
组件的控制。
// xxx.ets
@Entry
@Component
struct WebComponent {
controller: WebController = new WebController();
build() {
Column() {
Web({ src: 'https://developer.harmonyos.com/', controller: this.controller })
}
}
}
代码运行效果图如下:
访问在线网页时您需要在module.json5
文件中申明网络访问权限:ohos.permission.INTERNET
。
{
"module" : {
"requestPermissions":[
{
"name": "ohos.permission.INTERNET"
}
]
}
}
前面实现了Web
组件加载在线网页,Web
组件同样也可以加载本地网页。首先在main/resources/rawfile
目录下创建一个HTML
文件,然后通过$rawfile
引用本地网页资源,示例代码如下:
// xxx.ets
@Entry
@Component
struct SecondPage {
controller: WebController = new WebController();
build() {
Column() {
Web({ src: $rawfile('index.html'), controller: this.controller })
}
}
}
// xxx.html
代码运行效果图如下:
为了方便开发者学习,后面用到的HTML
都是以文件的形式放到rawfile
目录下,加载本地网页。
有的网页可能不能很好适配手机屏幕,需要对其缩放才能有更好的效果,开发者可以根据需要给Web组件设置zoomAccess属性,zoomAccess用于设置是否支持手势进行缩放,默认允许执行缩放。Web组件默认支持手势进行缩放。
Web({ src:'www.example.com', controller:this.controller })
.zoomAccess(true)
您还可以使用zoom(factor: number)
方法用于设置网站的缩放比例。其中factor
表示缩放倍数,下面示例,当点击一次按钮时,页面放大为原来的1.5倍。
// xxx.ets
@Entry
@Component
struct 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 })
}
}
}
说明
需要注意的是只有网页自身支持缩放,才能在Web
组件里面进行缩放。
如果需要对文本进行缩放,可以使用textZoomAtio(textZoomAtio: number)
方法。其中textZoomAtio
用于设置页面的文本缩放百分比,默认值为100,表示100%,以下示例代码将文本放大为原来的1.5倍。
Web({ src:'www.example.com', controller:this.controller })
.textZoomAtio(150)
效果图如下:
从上面的效果图可以看出使用textZoomAtio
,文本会放大,但是图片不会随着文本一起放大。
Web
组件还提供了处理Javascript
的对话框、网页加载进度及各种通知与请求事件的方法。例如onProgressChange
可以监听网页的加载进度,onPageEnd
在网页加载完成时触发该回调,且只在主frame触发,onConfirm
则在网页触发confirm
告警弹窗时触发回调。下面以onConfirm
事件为例讲解Web组件事件的使用,更多Web
组件事件可以查看事件。
如果您希望响应Web组件中网页的警告弹窗事件,您可以在onAlert
或者onConfirm
的回调方法中处理这些事件。以confirm
弹窗为例,在网页触发onConfirm()
告警弹窗时,显示一个AlertDialog
弹窗。
// xxx.ets
@Entry
@Component
struct WebComponent {
controller:WebController = new WebController();
build() {
Column() {
Web({ src:$rawfile('index.html'), controller:this.controller })
.onConfirm((event) => {
AlertDialog.show({
title: 'title',
message: event.message,
confirm: {
value: 'onAlert',
action: () => {
event.result.handleConfirm();
}
},
cancel: () => {
event.result.handleCancel();
}
})
return true;
})
}
}
}
当onConfirm
回调返回false
时,触发默认弹窗。当回调返回true
时,系统应用可以调用系统弹窗能力(包括确认和取消),并且需要根据用户的确认或取消操作调用JsResult
通知Web
组件。
在rawfile
目录下创建如下HTML
文件:
在开发专为适配Web组件的网页时,您可以实现Web组件和JavaScript代码之间的交互。Web组件可以调用JavaScript方法,JavaScript也可以调用Web组件里面的方法。
如果您希望加载的网页在Web组件中运行JavaScript,则必须为您的Web组件启用JavaScript功能,默认情况下是允许JavaScript执行的。
Web({ src:'https://www.example.com', controller:this.controller })
.javaScriptAccess(true)
您可以在Web组件onPageEnd事件中添加runJavaScript方法。事件是网页加载完成时的回调,runJavaScript方法可以执行HTML中的JavaScript脚本。
// xxx.ets
@Entry
@Component
struct 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;
}});
})
}
}
}
当页面加载完成时,触发onPageEnd
事件,调用HTML
文件中的test
方法并将结果返回给Web
组件。
您可以使用registerJavaScriptProxy
将Web
组件中的JavaScript
对象注入到window
对象中,这样网页中的JS
就可以直接调用该对象了。需要注意的是,要想registerJavaScriptProxy
方法生效,须调用refresh
方法。下面的示例将ets文件中的对象testObj
注入到了window
对象中。
// xxx.ets
@Entry
@Component
struct 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
里面对应的方法即可,示例如下:
// index.html
调用Web组件里面的方法
你还可以使用deleteJavaScriptRegister
删除通过registerJavaScriptProxy
注册到window上的指定name
的应用侧JavaScript
对象。
当我们在使用浏览器浏览网页时,可以执行返回、前进、刷新等操作,Web
组件同样支持这些操作。您可以使用backward()
返回到上一个页面,使用forward()
前进一个页面,您也可以使用refresh()
刷新页面,使用clearHistory()
来清除历史记录。下面通过一个简单的”浏览器”示例呈现这些功能。
// xxx.ets
@Entry
@Component
struct Page5 {
controller: WebController = new WebController();
build() {
Column() {
Row() {
Button("前进").onClick(() => {
this.controller.forward();
})
Button("后退").onClick(() => {
this.controller.backward();
})
Button("刷新").onClick(() => {
this.controller.refresh();
})
Button("停止").onClick(() => {
this.controller.stop();
})
Button("清除历史").onClick(() => {
this.controller.clearHistory();
})
}
.padding(12)
.backgroundColor(Color.Gray)
.width('100%')
Web({ src: 'https://developer.harmonyos.com/', controller: this.controller })
}
.height('100%')
}
}
您可以使用accessBackward()
来检查当前页面是否有后退来时记录,如果有则该方法返回 true
。同样,您可以使用 accessForward()
来检查是否存在前进历史记录。
您可以使用onConsole
获取网页输出的调试日志信息,当你在你的网页中使用console
打印日志时,HarmonyOS
系统都会调用相应的onConsole
方法,这样你就可以获取到网页日志信息了。下面展示了如何在Web
组件中使用onConsole
输出网页中的日志:
// xxx.ets
@Entry
@Component
struct WebComponent {
controller: WebController = new WebController();
build() {
Column() {
Web({ src: $rawfile('index.html'), controller: this.controller })
.onConsole((event) => {
console.log('getMessage:' + event.message.getMessage());
console.log('getMessageLevel:' + event.message.getMessageLevel());
return false;
})
}
}
}
// index.html
event
的内容为ConsoleMessage
,它包括一个对象来表示正在传递的日志信息的MessageLevel
类型。您可以使用getMessageLevel()
查询消息级别以确定消息的严重性,然后根据自身业务采取相应的操作。上面的示例代码,会打印如下所示的 日志消息:
08-27 19:47:27.476 27869-27937/com.example.webtest D 03B00/JSApp: app Log: getMessage:info message
08-27 19:47:27.476 27869-27937/com.example.webtest D 03B00/JSApp: app Log: getMessageLevel:3
08-27 19:47:27.478 27869-27937/com.example.webtest D 03B00/JSApp: app Log: getMessage:error message
08-27 19:47:27.478 27869-27937/com.example.webtest D 03B00/JSApp: app Log: getMessageLevel:1
案例源码下载:
Web组件抽奖案例(ArkTS)-示例源码