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  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  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  492