尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

HarmonyOS Web 加载完成后内容渐显 + 原生标题同步(实战模板)

HarmonyOS Web 加载完成后内容渐显 + 原生标题同步(实战模板)
📅 发布时间:2026/6/19 20:03:06

HarmonyOS Web 加载完成后内容渐显 + 原生标题同步(实战模板)

一起来构建生态吧~

做 HarmonyOS 的 Web 组件(ArkWeb),我最在意的两个体验点其实很“用户视角”:

  1. 加载完成那一下,别突然“啪”地一跳(看起来像闪屏/卡顿)
  2. 原生标题栏要跟网页标题同步(不然一会儿显示 URL、一会儿空白,特别不专业)

这一篇我直接给你一套工程里能长期复用的模板:
Web 加载完成后 内容渐显(opacity 淡入)
原生标题 自动跟随网页 title,并且处理 onTitleReceive 返回 URL 的情况

背景知识:Web 组件支持 onTitleReceive 通知“document 标题变化”。如果页面没设置 title,ArkWeb 可能在加载完成前基于 URL 生成标题返回给应用。官方也建议配合 getTitle 获取当前标题。:contentReference[oaicite:0]


一、整体思路(先说清楚)

1)内容渐显怎么做?

  • Web 组件一直在(不要加载完才创建)
  • 初始 opacity = 0
  • 在 onPageEnd(或进度到一定值)时 animateTo 让 opacity -> 1

2)标题同步怎么做?

标题我推荐走两条路兜底:

  • 主路径:onTitleReceive 拿到标题就更新
  • 兜底路径:onPageEnd 时 runJavaScript('document.title') 再取一次
    • 因为实践里有时 onTitleReceive 可能先回 URL 或不稳定(尤其页面没写 <title> 时):contentReference[oaicite:1]

二、完整页面模板(可直接用)

你可以新建 WebFadeTitleSyncPage.ets,复制进去跑。

import { webview } from '@kit.ArkWeb';@Entry
@Component
struct WebFadeTitleSyncPage {private controller: webview.WebviewController = new webview.WebviewController();// 原生标题@State navTitle: string = '加载中…';// 渐显动画@State webOpacity: number = 0;@State isLoading: boolean = true;@State progress: number = 0;private fadeInWeb() {if (this.webOpacity >= 1) return;animateTo({ duration: 260, curve: Curve.EaseOut }, () => {this.webOpacity = 1;});}private updateTitleSafely(title?: string) {const t = (title ?? '').trim();// 过滤掉过短/空标题if (!t) return;// 有些场景 onTitleReceive 会先回 URL(尤其页面没设置 title)// 简单判断:像 URL 就先别抢占用户视线,等 onPageEnd 再兜底一次const looksLikeUrl =t.startsWith('http://') || t.startsWith('https://') || t.includes('://');if (looksLikeUrl && this.navTitle !== '加载中…') {return;}this.navTitle = t;}private async syncTitleFromDom() {// 用 JS 再取一次 document.title 做兜底(避免 onTitleReceive 返回 URL)try {this.controller.runJavaScript('document.title', (result: string) => {// result 的具体格式与实现有关:有的会带引号或是 JSON 字符串// 这里做一个简单清洗const cleaned = (result ?? '').replace(/^"+|"+$/g, '').trim();this.updateTitleSafely(cleaned);});} catch (e) {// 忽略:有些时机 Web 还没 ready 会失败}}build() {Column() {// ===== 原生标题栏(你也可以换成自定义导航组件)=====Row() {Text(this.navTitle).fontSize(18).fontWeight(FontWeight.Bold).maxLines(1).textOverflow({ overflow: TextOverflow.Ellipsis })}.padding({ left: 16, right: 16, top: 12, bottom: 12 }).width('100%')// ===== Web 区域 =====Stack() {Web({src: 'https://example.com', // 换成你的 URL / rawfilecontroller: this.controller}).javaScriptAccess(true)// 页面开始加载:先把 Web 透明,标题设为“加载中”.onPageBegin(() => {this.isLoading = true;this.progress = 0;this.webOpacity = 0;this.navTitle = '加载中…';})// 进度:到一定程度可以提前淡入(体验更自然).onProgressChange((p: number) => {this.progress = p;if (p >= 80) {this.fadeInWeb();}})// 标题变化:优先用它同步标题// onTitleReceive:通知应用页面 document 标题已更改;如果页面没设置标题,可能返回 URL 形式:contentReference[oaicite:2]{index=2}.onTitleReceive((title: string) => {this.updateTitleSafely(title);})// 页面加载完成:兜底同步一次 title + 确保淡入.onPageEnd(() => {this.isLoading = false;this.fadeInWeb();this.syncTitleFromDom();}).opacity(this.webOpacity).width('100%').height('100%')// (可选)轻量 Loading 覆盖if (this.isLoading) {Column({ space: 8 }) {LoadingProgress()Text(`加载中 ${this.progress}%`).fontSize(12).opacity(0.65)}.width('100%').height('100%').justifyContent(FlexAlign.Center).backgroundColor('#FFFFFF').opacity(0.85)}}.width('100%').height('100%')}.width('100%').height('100%')}
}

三、为什么我建议“onTitleReceive + document.title 兜底”?

说人话就是:你别跟 Web 内核赌运气。

  • onTitleReceive 很好用,标题一变就能收到
  • 但如果页面没设置 <title>,ArkWeb 有可能会在加载完成前用 URL 生成标题返回给你(你看起来就像“标题栏显示了一串网址”)华为开发者官网+1
  • 所以 onPageEnd 再 runJavaScript('document.title') 取一次,基本就稳了

四、我项目里常加的一点“人性化细节”

1)标题别疯狂抖动

有些网页会频繁改 title(比如路由切换、埋点)。你可以:

  • 对 title 做 200ms 防抖再更新
  • 或者只在“页面完成加载后”才允许更新

2)淡入不要太慢

我习惯 220~280ms,超过 400ms 会显得“粘”。

相关新闻

  • Andrej Karpathy亲授:2025年大模型技术发展六大关键点
  • 3步搞定QMC音频解密:从加密格式到通用MP3/FLAC的完整转换方案
  • BetterNCM安装器完整使用手册:一键解锁网易云音乐隐藏功能

最新新闻

  • Windows老游戏终极兼容解决方案:dxwrapper完全指南
  • 编写自定义脚本来自动化 vLLM 部署流程
  • 宣城市宁国吃正宗皖南徽菜 + 宁国农家土菜推荐去哪家? - 速递信息
  • 武汉买猫买狗去哪看?梦宠山庄实地体验分享 - 园友3800037
  • 从零到一:Jetlinks物联网平台服务器部署实战与避坑指南
  • (转)一次ANSYS EM 2023R1 “Request name electronics_desktop does not exist in the licensing pool.“的离谱解决记录

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号