开发者可利用Web组件的焦点管理功能,有效管理Web组件的获焦与失焦,同时利用H5端的W3C标准接口,管理网页界面上唯一可交互的元素获焦与失焦。
Web组件与ArkUI组件焦点控制的常用接口及其使用场景:
Web组件内H5元素焦点控制的常用接口及其使用场景:
Web组件焦点、焦点链和走焦的详情说明请参考ArkUI焦点基础概念。
根据走焦的触发方式,可以分为主动走焦和被动走焦,Web组件走焦规范详情参考ArkUI走焦规范。
指开发者或用户主观行为导致的焦点移动。包括:使用requestFocus申请焦点、外接键盘的按键走焦(Tab键/Shift+Tab键)、点击申请焦点(手势/鼠标/触摸板)等导致的焦点转移。
requestFocus
详见Web组件与ArkUI组件焦点控制,可以主动将焦点转移到Web组件上。
按键走焦
点击申请获焦
开发者或用户可通过手势、鼠标或触摸板点击Web组件,使其主动获得焦点。当具体点击到Web组件内的某个元素时,该元素能够获得焦点,例如:点击网页内的输入框,可使其从不可编辑状态转变为可编辑状态,并激活输入法。
被动走焦指焦点因系统或其他操作而转移,无需开发者直接干预,是焦点系统的默认行为。
被动走焦的场景有:
组件移除:当焦点所在的Web组件被移除时,系统会按照先向后再向前的原则,将焦点转移至相邻的同级组件。若所有同级组件均不可获焦,则焦点将被释放,并通知其父级组件进行焦点处理。
属性变更:若将处于焦点状态的组件的focusable或enabled属性设置为false,或者将visibility属性设置为不可见,系统将自动转移焦点至其他可获焦组件,转移方式同组件移除。
Web组件不可见:Web组件获焦后,应用前后台切换、页面切换、Navigation导航等场景,Web组件会失焦再获焦。
Web组件加载网页:Web组件通过src、loadUrl、loadData加载网页,默认会获取焦点,但若此时Web组件为不可获焦状态则会获焦失败(常见的不可获焦状态原因有:转场动画过程中父组件不可获焦、应用侧设置了Web组件或其父组件不可获焦属性等),应用侧可以调用主动申请获焦接口requestFocus再次尝试使Web组件获焦。当获焦成功后,应用侧onFocus、W3C focus事件均会上报。
autofocus样式:设置了autofocus样式的元素网页完成加载时默认获焦。若该元素支持文本输入,则输入框会有光标闪烁,但不会弹出软键盘。如需自动弹出软键盘,可参考软键盘自动弹出。
菜单弹出:ArkUI的overlay属性类型组件默认抢焦,在与此类组件结合的Web组件场景中(Menu、DatePicker、TimePicker、下拉框、弹窗等),Web组件均会失焦。
示例:
- import { webview } from '@kit.ArkWeb';
- import { BusinessError } from '@kit.BasicServicesKit';
-
- @Entry
- @Component
- struct WebComponent {
- controller: webview.WebviewController = new webview.WebviewController();
- controller2: webview.WebviewController = new webview.WebviewController();
- @State webBorderColor: Color = Color.Red;
- @State webBorderColor2: Color = Color.Red;
-
- build() {
- Column() {
- Row() {
- Button('web1 requestFocus')
- .onClick(() => {
- try {
- this.controller.requestFocus();
- } catch (error) {
- console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
- }
- });
- Button('web2 requestFocus')
- .onClick(() => {
- try {
- this.controller2.requestFocus();
- } catch (error) {
- console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
- }
- });
- }
- Web({ src: 'www.example.com', controller: this.controller })
- .onFocus(() => {
- this.webBorderColor = Color.Green;
- })
- .onBlur(() => {
- this.webBorderColor = Color.Red;
- })
- // ···
- .margin(3)
- .borderWidth(10)
- .borderColor(this.webBorderColor)
- .height('45%')
-
- Web({ src: 'www.example.com', controller: this.controller2 })
- .onFocus(() => {
- this.webBorderColor2 = Color.Green;
- })
- .onBlur(() => {
- this.webBorderColor2 = Color.Red;
- })
- .margin(3)
- .borderWidth(10)
- .borderColor(this.webBorderColor2)
- .height('45%')
- }
- }
- }
示例图1 组件获焦/失焦事件
通过requestFocus接口主动请求获焦,并监听通用接口onFocus和onBlur事件,改变Web组件边框颜色。

- addEventListener("focus", (event) => {});
-
- onfocus = (event) => {};
- addEventListener("blur", (event) => {});
-
- onblur = (event) => {};
- <input name="q" autofocus />
在文档或对话框中,最多只能有一个元素具有 autofocus 属性。若应用于多个元素,第一个元素将获得焦点。
示例:
- import { webview } from '@kit.ArkWeb';
-
- @Entry
- @Component
- struct WebComponent {
- controller: webview.WebviewController = new webview.WebviewController();
-
- build() {
- Column() {
- Web({ src: $rawfile('test.html'), controller: this.controller })
- }
- }
- }
加载的html文件。
- <!-- test.html -->
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>test</title>
- </head>
- <body>
- <form id="form">
- <input type="text" placeholder="text input" />
- <input type="password" placeholder="password" />
- </form>
- </body>
- <script>
- const form = document.getElementById("form");
- form.addEventListener(
- "focus",
- (event) => {
- event.target.style.background = "pink";
- },
- true,
- );
- form.addEventListener(
- "blur",
- (event) => {
- event.target.style.background = "";
- },
- true,
- );
- </script>
- </html>
示例图2 Web组件内元素焦点获焦/失焦事件
通过监听W3C接口focus和blur事件,改变输入背景色。
