• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 使用Web组件显示网页弹框
2<!--Kit: ArkWeb-->
3<!--Subsystem: Web-->
4<!--Owner: @zourongchun-->
5<!--Designer: @zhufenghao-->
6<!--Tester: @ghiker-->
7<!--Adviser: @HelloCrease-->
8
9在HTML中,可以使用JavaScript创建三种类型的弹框:警告框`window.alert(message)`、确认框`window.confirm(message)`和提示框`window.prompt(message, defaultValue)`。这些弹框可以用于向用户传递信息、确认操作或请求输入。
10
11当前,ArkWeb暂未提供默认的应用弹框。如果需要网页的弹框能够正常使用,应用需要通过[onAlert](../reference/apis-arkweb/arkts-basic-components-web-events.md#onalert)、[onConfirm](../reference/apis-arkweb/arkts-basic-components-web-events.md#onconfirm)和[onPrompt](../reference/apis-arkweb/arkts-basic-components-web-events.md#onprompt9)接口自定义弹框功能。
12
13## 实现Alert弹框
14
15`window.alert()`用于显示一个包含可选信息的对话框。警告框用于确保用户可以得到某些信息。当警告框出现后,用户需要点击确定按钮才能继续进行操作。
16- 可选参数`message`是要显示在警告对话框中的字符串,如果传入其他类型的值,会转换成字符串。
17- 该方法不存在返回值。
18
19应用可以通过[onAlert](../reference/apis-arkweb/arkts-basic-components-web-events.md#onalert)事件监听网页`alert`方法,并创建合适的弹框。
20
21- 用[AlertDialog](../reference/apis-arkui/arkui-ts/ts-methods-alert-dialog-box.md)创建弹框。
22
23  ```ts
24  import { webview } from '@kit.ArkWeb';
25
26  @Entry
27  @Component
28  struct Index {
29    @State message: string = 'Hello World';
30    webviewController: webview.WebviewController = new webview.WebviewController();
31    uiContext: UIContext = this.getUIContext();
32
33    build() {
34      Row() {
35        Web({ src: $rawfile('test.html'), controller: this.webviewController })
36          .onAlert((event) => {
37            if (event) {
38              console.log("event.url:" + event.url);
39              console.log("event.message:" + event.message);
40              this.uiContext.showAlertDialog({
41                title: "来自" + event.url + "的警告",
42                message: event.message,
43                confirm:{
44                  value: "确认",
45                  action: ()=>{
46                    console.info('Alert confirmed.');
47                    event.result.handleConfirm();
48                  }
49                },
50                cancel: () => {
51                  event.result.handleCancel();
52                }
53              })
54            }
55            return true;
56          })
57      }
58    }
59  }
60  ```
61  加载的html。
62  ```html
63  <!doctype html>
64  <html lang="en">
65  <head>
66      <meta charset="UTF-8">
67      <meta name="viewport"
68            content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
69      <meta http-equiv="X-UA-Compatible" content="ie=edge">
70      <title>Document</title>
71      <style>
72          button,label,input {
73          margin: 5px 0;
74          }
75      </style>
76  </head>
77  <body>
78  <input type="text" id="alert-message" placeholder="message for alert"><br/>
79  <button onclick="handleAlert()">alert</button><br/>
80  <script>
81      function handleAlert() {
82          let message = document.getElementById("alert-message").value;
83          let result = window.alert(message ? message : 'alert');
84      }
85  </script>
86  </body>
87  </html>
88  ```
89
90- 用[CustomDialog-AlertDialog](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Dialog.md#alertdialog)创建弹框。
91
92  ```ts
93  import { AlertDialog, router } from '@kit.ArkUI';
94  import { webview } from '@kit.ArkWeb';
95
96  @Entry
97  @Component
98  struct AlertDialogPage {
99    @State message: string = 'Hello World';
100    @State title: string = 'Hello World';
101    @State subtitle: string = '';
102    @State result: JsResult | null = null;
103    webviewController: webview.WebviewController = new webview.WebviewController();
104    dialogControllerAlert: CustomDialogController = new CustomDialogController({
105      builder: AlertDialog({
106        primaryTitle: this.title,
107        secondaryTitle: this.subtitle,
108        content: this.message,
109        primaryButton: {
110          value: '确认',
111          role: ButtonRole.ERROR,
112          action: () => {
113            console.info('Callback when the second button is clicked');
114            this.result?.handleConfirm();
115          }
116        },
117      }),
118      onWillDismiss: ()=>{
119        this.result?.handleCancel();
120        this.dialogControllerAlert.close();
121      }
122    })
123
124    build() {
125      Column() {
126        Button('back').onClick((event: ClickEvent) => {
127          this.getUIContext().getRouter().back();
128        })
129        Web({ src: $rawfile('alert.html'), controller: this.webviewController })
130          .onAlert((event) => {
131            if (event) {
132              console.log("event.url:" + event.url);
133              console.log("event.message:" + event.message);
134              this.title = "来自" + event.url + "的警告";
135              this.message = event.message;
136              this.result = event.result;
137              this.dialogControllerAlert.open();
138            }
139            return true;
140          })
141      }
142    }
143  }
144  ```
145  加载的html。
146  ```html
147  <!doctype html>
148  <html lang="en">
149  <head>
150      <meta charset="UTF-8">
151      <meta name="viewport"
152            content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
153      <meta http-equiv="X-UA-Compatible" content="ie=edge">
154      <title>Document</title>
155      <style>
156          button,label,input {
157          margin: 5px 0;
158          }
159      </style>
160  </head>
161  <body>
162  <input type="text" id="alert-message" placeholder="message for alert"><br/>
163  <button onclick="handleAlert()">alert</button><br/>
164  <script>
165      function handleAlert() {
166          let message = document.getElementById("alert-message").value;
167          let result = window.alert(message ? message : 'alert');
168      }
169  </script>
170  </body>
171  </html>
172  ```
173
174  ![AlertDialog](./figures/web-alert-dialog.gif)
175
176## 实现Confirm弹框
177
178`window.confirm()`用于显示一个包含可选消息的对话框,并等待用户确认或取消该对话框。
179- 可选参数`message`是要显示在对话框中的字符串,如果传入其他类型的值,会转换成字符串。
180- 该方法返回一个布尔值,表示是否选择了确定(`true`)或取消(`false`)。如果应用忽略了页面内的对话框,那么返回值总是`false`。
181
182确认框用于验证用户是否接受某个操作,常用于询问用户是否离开网页,以防页面表单等数据丢失。
183
184应用可以通过[onConfirm](../reference/apis-arkweb/arkts-basic-components-web-events.md#onconfirm)事件监听网页`confirm`方法,并创建合适的弹框。
185
186- 用[AlertDialog](../reference/apis-arkui/arkui-ts/ts-methods-alert-dialog-box.md)创建弹框。
187
188  ```ts
189  import { webview } from '@kit.ArkWeb';
190
191  @Entry
192  @Component
193  struct Index {
194    @State message: string = 'Hello World';
195    webviewController: webview.WebviewController = new webview.WebviewController();
196    uiContext: UIContext = this.getUIContext();
197
198    build() {
199      Column() {
200        Web({ src: $rawfile('test.html'), controller: this.webviewController })
201          .onConfirm((event) => {
202            if (event) {
203              console.log("event.url:" + event.url);
204              console.log("event.message:" + event.message);
205              this.uiContext.showAlertDialog({
206                title: "来自" + event.url + "的消息",
207                message: event.message,
208                primaryButton: {
209                  value: 'cancel',
210                  action: () => {
211                    event.result.handleCancel();
212                  }
213                },
214                secondaryButton: {
215                  value: 'ok',
216                  action: () => {
217                    event.result.handleConfirm();
218                  }
219                },
220                cancel: () => {
221                  event.result.handleCancel();
222                }
223              })
224            }
225            return true;
226          })
227      }
228    }
229  }
230  ```
231
232  加载的html。
233  ```html
234  <!doctype html>
235  <html lang="en">
236  <head>
237      <meta charset="UTF-8">
238      <meta name="viewport"
239            content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
240      <meta http-equiv="X-UA-Compatible" content="ie=edge">
241      <title>Document</title>
242      <style>
243          button,label,input {
244          margin: 5px 0;
245          }
246      </style>
247  </head>
248  <body>
249  result:<label id="confirmLabel" for="confirm"></label><br/>
250  <input type="text" id="confirm-message" placeholder="message for confirm"><br/>
251  <button id="confirm" onclick="handleConfirm()">confirm</button><br/>
252  <script>
253      function handleConfirm() {
254          let message = document.getElementById("confirm-message").value;
255          let result = window.confirm(message ? message : 'confirm');
256          console.log(result);
257          document.getElementById("confirmLabel").innerHTML=String(result);
258      }
259  </script>
260  </body>
261  </html>
262  ```
263
264- 用[CustomDialog-ConfirmDialog](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Dialog.md#confirmdialog)创建弹框。
265
266  ```ts
267  import { webview } from '@kit.ArkWeb';
268  import { ConfirmDialog } from '@kit.ArkUI';
269
270  @Entry
271  @Component
272  struct DialogConfirmDialog {
273    @State message: string = 'Hello World';
274    @State title: string = 'Hello World';
275    @State result: JsResult | null = null;
276    webviewController: webview.WebviewController = new webview.WebviewController();
277    isChecked = false;
278    dialogControllerCheckBox: CustomDialogController = new CustomDialogController({
279      builder: ConfirmDialog({
280        title: this.title,
281        content: this.message,
282        // 勾选框选中状态
283        isChecked: this.isChecked,
284        // 勾选框说明文本
285        checkTips: '禁止后不再提示',
286        primaryButton: {
287          value: '禁止',
288          action: () => {
289            this.result?.handleCancel();
290          },
291        },
292        secondaryButton: {
293          value: '允许',
294          action: () => {
295            this.isChecked = false;
296            console.info('Callback when the second button is clicked');
297            this.result?.handleConfirm();
298          }
299        },
300        onCheckedChange: (checked) => {
301          this.isChecked = checked;
302          console.info('Callback when the checkbox is clicked');
303        },
304      }),
305      onWillDismiss: () => {
306        this.result?.handleCancel();
307        this.dialogControllerCheckBox.close();
308      },
309      autoCancel: true
310    })
311
312    build() {
313      Column() {
314        Web({ src: $rawfile('confirm.html'), controller: this.webviewController })
315          .onConfirm((event) => {
316            if (event) {
317              if (this.isChecked) {
318                event.result.handleCancel();
319              } else {
320                console.log("event.url:" + event.url);
321                console.log("event.message:" + event.message);
322                this.title = "来自" + event.url + "的消息";
323                this.message = event.message;
324                this.result = event.result;
325                this.dialogControllerCheckBox.open();
326              }
327            }
328            return true;
329          })
330      }
331    }
332  }
333  ```
334  加载的html。
335  ```html
336  <!doctype html>
337  <html lang="en">
338  <head>
339      <meta charset="UTF-8">
340      <meta name="viewport"
341            content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
342      <meta http-equiv="X-UA-Compatible" content="ie=edge">
343      <title>Document</title>
344      <style>
345          button,label,input {
346          margin: 5px 0;
347          }
348      </style>
349  </head>
350  <body>
351  result:<label id="confirmLabel" for="confirm"></label><br/>
352  <input type="text" id="confirm-message" placeholder="message for confirm"><br/>
353  <button id="confirm" onclick="handleConfirm()">confirm</button><br/>
354  <script>
355      function handleConfirm() {
356          let message = document.getElementById("confirm-message").value;
357          let result = window.confirm(message ? message : 'confirm');
358          console.log(result);
359          document.getElementById("confirmLabel").innerHTML=String(result);
360      }
361  </script>
362  </body>
363  </html>
364  ```
365
366  ![ConfirmDialog](./figures/web-confirm-dialog.gif)
367
368## 实现Prompt弹框
369
370`window.prompt()`用于显示一个对话框,并等待用户提交文本或取消对话框。用户需要输入某个值,然后点击确认或取消按钮。点击确认返回输入的值,点击取消返回`null`。
371- 可选参数`message`向用户显示的一串文本。如果在提示窗口中没有什么可显示的,可以省略。
372- 可选参数`defaultValue`是一个字符串,包含文本输入字段中显示的默认值。
373- 返回值为用户输入文本的字符串,或`null`。
374
375提示框用于提示用户输入某个值,常用于需要用户输入临时的口令或验证码等场景。
376
377应用可以通过[onPrompt](../reference/apis-arkweb/arkts-basic-components-web-events.md#onprompt9)事件监听网页`prompt`方法,并创建合适的弹框。
378
379- 用[CustomDialog-CustomContentDialog](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Dialog.md#customcontentdialog12)创建弹框。
380
381  ```ts
382  import { CustomContentDialog } from '@kit.ArkUI';
383  import { webview } from '@kit.ArkWeb';
384
385  @Entry
386  @Component
387  struct PromptDialog {
388    @State message: string = 'Hello World';
389    @State title: string = 'Hello World';
390    @State result: JsResult | null = null;
391    promptResult: string = '';
392    webviewController: webview.WebviewController = new webview.WebviewController();
393    dialogController: CustomDialogController = new CustomDialogController({
394      builder: CustomContentDialog({
395        primaryTitle: this.title,
396        contentBuilder: () => {
397          this.buildContent();
398        },
399        buttons: [
400          {
401            value: '取消',
402            buttonStyle: ButtonStyleMode.TEXTUAL,
403            action: () => {
404              console.info('Callback when the button is clicked');
405              this.result?.handleCancel();
406            }
407          },
408          {
409            value: '确认',
410            buttonStyle: ButtonStyleMode.TEXTUAL,
411            action: () => {
412              this.result?.handlePromptConfirm(this.promptResult);
413            }
414          }
415        ],
416      }),
417      onWillDismiss: () => {
418        this.result?.handleCancel();
419        this.dialogController.close();
420      }
421    });
422
423    // 自定义弹出框的内容区
424    @Builder
425    buildContent(): void {
426      Column() {
427        Text(this.message)
428        TextInput()
429          .onChange((value) => {
430            this.promptResult = value;
431          })
432          .defaultFocus(true)
433      }
434      .width('100%')
435    }
436
437    build() {
438      Column() {
439        Web({ src: $rawfile('prompt.html'), controller: this.webviewController })
440          .onPrompt((event) => {
441            if (event) {
442              console.log("event.url:" + event.url);
443              console.log("event.message:" + event.message);
444              console.log("event.value:" + event.value);
445              this.title = "来自" + event.url + "的消息";
446              this.message = event.message;
447              this.promptResult = event.value;
448              this.result = event.result;
449              this.dialogController.open();
450            }
451            return true;
452          })
453      }
454    }
455  }
456  ```
457  加载的html。
458  ```html
459  <!doctype html>
460  <html lang="en">
461  <head>
462      <meta charset="UTF-8">
463      <meta name="viewport"
464            content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
465      <meta http-equiv="X-UA-Compatible" content="ie=edge">
466      <title>Document</title>
467      <style>
468          button,label,input {
469          margin: 5px 0;
470          }
471      </style>
472  </head>
473  <body>
474  result:<label id="promptLabel" for="prompt"></label><br/>
475  <input type="text" id="prompt-message" placeholder="message for prompt"><br/>
476  <input type="text" id="prompt-value" placeholder="default value for prompt"><br/>
477  <button id="prompt" onclick="handlePrompt()">prompt</button><br/>
478  <script>
479      function handlePrompt() {
480          let message = document.getElementById("prompt-message").value;
481          let defaultValue = document.getElementById("prompt-value").value;
482          let result = window.prompt(message ? message : 'prompt', defaultValue);
483          console.log(result);
484          document.getElementById("promptLabel").innerHTML=result;
485      }
486  </script>
487  </body>
488  </html>
489  ```
490
491  ![PromptDialog](./figures/web-prompt-dialog.gif)
492