news 2026/5/23 13:16:33

鸿蒙中 Web 组件在新窗口打开链接

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙中 Web 组件在新窗口打开链接

本文同步发表于 微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

当 Web 组件加载的网页(如通过window.open())尝试打开新窗口时,系统并不会自动创建,而是会通知应用层,由开发者决定如何响应该请求(如在弹窗、新页面或新窗口中展示)。这是一个典型的 “通知-响应” 模型。

整个交互流程的角色与步骤如下:

  1. 网页侧:调用window.open()等方法请求新窗口。

  2. ArkWeb 内核:拦截请求,检查name参数对应的 Web 组件是否存在。

  3. 应用侧:通过onWindowNew()回调接收事件,创建新窗口(如CustomDialog)并建立关联。

二、API 与配置

为了启用并管理新窗口行为,需要使用一组特定的属性和回调接口,其作用和关系如下表:

接口/配置所属组件作用与说明关键点
.multiWindowAccess(true)Web 组件属性总开关:允许网页请求打开新窗口。必须设置为true,否则后续流程不会触发。
.allowWindowOpenMethod(true)Web 组件属性脚本开关:允许网页通过window.open()等 JavaScript 方式打开新窗口。通常与multiWindowAccess配合使用。
.onWindowNew(event)Web 组件事件回调核心事件:当网页请求新窗口时触发。开发者需在此回调中创建新窗口并建立关联。回调参数event中的handler是连接新窗口与内核的关键桥梁
event.handler.setWebController(controller)onWindowNew事件参数方法建立关联:将你为新窗口创建的WebviewController实例告知 ArkWeb 内核,使内核能将新网页内容注入该控制器关联的 Web 组件。必须调用,否则渲染进程会阻塞。若无新窗口,参数需设为null
.onActivateContent()Web 组件事件回调激活通知:当网页尝试通过window.open(url, name)打开一个已存在的name窗口时,对应name的 Web 组件会收到此回调,提示应用将其展示到前台(如切换 Tab)。此回调作用于目标窗口对应的 Web 组件,而非发起请求的源组件。

三、示例代码

// 1. 定义新窗口的UI组件(这里使用CustomDialog模拟弹窗窗口) @CustomDialog struct NewWebViewComp { controller?: CustomDialogController; // 为新窗口创建一个独立的控制器 webviewController1: webview.WebviewController = new webview.WebviewController(); build() { Column() { // 新窗口内的Web组件,初始无内容,将由内核注入 Web({ src: "", controller: this.webviewController1 }) .javaScriptAccess(true) .multiWindowAccess(false) // 此新窗口自身不允许再开窗口(根据需要设置) .onWindowExit(() => { /* 窗口关闭处理 */ }) .onActivateContent(() => { // 如果此窗口已被绑定过name,再次被请求打开时会触发这里 console.info("NewWebViewComp onActivateContent") }) } } } @Entry @Component struct WebComponent { // 主窗口的控制器 controller: webview.WebviewController = new webview.WebviewController(); // 用于控制新弹窗 dialogController: CustomDialogController | null = null; build() { Column() { // 2. 主Web组件:加载本地网页,并开启多窗口支持 Web({ src: $rawfile("window.html"), controller: this.controller }) .javaScriptAccess(true) .multiWindowAccess(true) // 总开关:允许打开新窗口 .allowWindowOpenMethod(true) // 允许JS的window.open() // 3. 核心:处理新窗口请求 .onWindowNew((event) => { // 关闭可能已存在的旧弹窗 if (this.dialogController) { this.dialogController.close() } // 为新窗口创建控制器 let popController: webview.Webview.WebviewController = new webview.WebviewController(); // 创建并打开一个自定义弹窗作为“新窗口” this.dialogController = new CustomDialogController({ builder: NewWebViewComp({ webviewController1: popController }), isModal: false // 设置为非模态,防止影响onActivateContent回调 }); this.dialogController.open(); // 4. 关键一步:将新窗口的控制器告知Web内核,建立绑定 event.handler.setWebController(popController); // 如果不调用setWebController或传入null,内核会认为应用未创建新窗口 }) } } }

网页 (window.html) 代码

<!DOCTYPE html> <html> <body> <!-- 点击按钮,触发 window.open() --> <input type="button" value="新窗口中打开网页" onclick="OpenNewWindow()"> <script type="text/javascript"> function OpenNewWindow() { // 打开一个空白页,并写入一些内容 let openedWindow = window.open("about:blank", "", "location=no,status=no,scrollbars=no"); openedWindow.document.write("<p><br><br>打开的窗口</p>"); openedWindow.focus(); } </script> </body> </html>

四、原理

五、注意事项

  1. setWebController必须调用:在onWindowNew回调中,无论是否创建新窗口,都必须调用event.handler.setWebController(...)。如果不调用,会导致 Web 内核的渲染进程阻塞等待

  2. 模态窗口与非模态窗口:使用CustomDialogController时,如果isModal设为true(模态),在某些情况下可能会影响后续onActivateContent等回调的触发。

  3. 内存与生命周期管理

    • 为新窗口创建的WebviewControllerCustomDialogController需要妥善管理(如在onWindowExit回调中关闭和释放),防止内存泄漏。

    • onWindowExit回调中关闭弹窗。

  4. onActivateContent的使用:这个回调是实现类似浏览器“标签页复用”功能的关键。当用户多次点击打开同一个“命名窗口”(name相同)时,可以将已存在的窗口激活并提到前台,而不是重复创建。

  5. OnWindowNewEvent.isUserTrigger参数:在OnWindowNewEvent回调函数中有一个isUserTrigger参数,可用于区分新窗口请求是由用户主动操作(如点击)触发,还是由网页脚本自动触发。有助于更精细的控制。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/20 15:58:18

压测 把自己 压进去了

凌晨一点&#xff0c;城中村的出租屋里&#xff0c;只有电脑屏幕的蓝光映着小李的脸。作为一名自由后端开发者&#xff0c;他不用受公司制度约束&#xff0c;日常接些接口开发、bug修复的散活&#xff0c;大把空闲时间都耗在了钻研技术上——而压测各类接口&#xff0c;成了他藏…

作者头像 李华
网站建设 2026/5/22 22:01:16

项目的逻辑和流程

项目的逻辑和流程 在互联网项目的推进过程中&#xff0c;清晰的逻辑框架和规范的执行流程是保障项目稳定落地的核心。无论是小型工具开发还是大型系统搭建&#xff0c;都离不开“从无到有、从测试到上线”的全流程管控。 一、项目核心逻辑阶段核心目标关键动作参与角色交付成果…

作者头像 李华
网站建设 2026/5/22 17:45:47

招聘外包口碑品牌榜前10名测评+选型全套指南!

“旺季急招50人&#xff0c;外包承诺3天到岗&#xff0c;结果一周才凑20人&#xff0c;一半还不会用系统”“花大价钱找外包&#xff0c;招来的人连基础操作都不会&#xff0c;直接亏了几十万”……做HR的谁没在招聘外包上踩过坑&#xff1f;现在招聘外包市场规模超3000亿&…

作者头像 李华
网站建设 2026/5/20 15:57:54

Docker 核心概念与价值详解:从理论到实战安装指南

Docker 核心概念与价值详解&#xff1a;从理论到实战安装指南 作为一名网络工程师&#xff0c;在接触自动化运维、云原生技术的过程中&#xff0c;Docker 是绕不开的核心工具。它凭借轻量级、可移植、快速部署的特性&#xff0c;彻底改变了应用的打包、分发和运行方式。本文将…

作者头像 李华
网站建设 2026/5/20 18:19:18

Buck电源仿真设计,基于MATLAB/Simulink建模仿真。 使用Control System

Buck电源仿真设计&#xff0c;基于MATLAB/Simulink建模仿真。 使用Control System Tool的sisotool模块&#xff0c;对Buck电路的控制环参数进行设计&#xff0c;可以一键生成传递函数&#xff0c;生成bode图。 可以进行PI参数整定。 仿真模型验证。 包含word文档对建模和校正过…

作者头像 李华
网站建设 2026/5/21 18:23:36

8款AI论文工具一站式操作指南:免费写开题报告超简单

你是不是正对着空白的文档发呆&#xff0c;不知如何下笔写开题报告&#xff1f;或者面对海量文献&#xff0c;感觉无从下手&#xff1f;别担心&#xff0c;随着AI技术的发展&#xff0c;现在有了一系列强大的工具&#xff0c;可以成为你学术道路上的“神助攻”。本文将为你带来…

作者头像 李华