【Web/HarmonyOS】采用ArkTS+Web组件开发网页嵌套的全屏应用

发布于:2025-05-13 ⋅ 阅读:(9) ⋅ 点赞:(0)

1、简介

在鸿蒙应用开发领域,技术选型的迭代速度令人瞩目。继昨日完成Vue框架的鸿蒙HelloWorld实践后,今日笔者深度体验了ArkTS+Web组件的开发范式,成功构建了一个支持双网页嵌套的全屏应用。本文将完整复现开发过程,重点解析全屏实现、网页嵌套等核心技术要点。

2、效果

在这里插入图片描述

3、在ArkTs上全屏Web

3.1、创建ArkTS应用

同样采用DevEco的IDE创建应用,可以参考我上一篇文章《【Web】使用Vue3开发鸿蒙的HelloWorld!》。

3.2、修改模块化配置(module.json5)

可以参考我的应用路径
在这里插入图片描述

修改module.json5源码如下:

{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "EntryAbility",
    "deviceTypes": [
      "phone"
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ts",
        "description": "$string:EntryAbility_desc",
        "icon": "$media:icon",
        "label": "$string:EntryAbility_label",
        "startWindowIcon": "$media:icon",
        "startWindowBackground": "$color:start_window_background",
        "exported": true,
        "skills": [
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "action.system.home"
            ]
          }
        ]
      }
    ],
  }
}

3.3、修改系统栏控制(ArkTS代码)

可以参考我的应用路径
在这里插入图片描述
修改Index.ets源码如下:

import web_webview from '@ohos.web.webview'
import window from '@ohos.window'
import common from '@ohos.app.ability.common'

@Entry
@Component
struct WebPage {
  controller: web_webview.WebviewController = new web_webview.WebviewController()
  private context = getContext(this) as common.Context

  async aboutToAppear() {
    try {
      // 获取窗口对象并设置全屏
      const win = await window.getLastWindow(this.context)

      // 核心配置:全屏+隐藏系统栏
      await win.setWindowLayoutFullScreen(true)
      await win.setWindowSystemBarEnable([])

      // 设置状态栏完全透明(防止出现白条)
      await win.setWindowSystemBarProperties({
        statusBarColor: '#00000000',
        navigationBarColor: '#00000000',
        statusBarContentColor: '#FF000000' // 状态栏图标颜色
      })

      // 禁用边缘手势(可选)
      await win.setWindowTouchable(false)
    } catch (err) {
      console.error('全屏配置失败:', JSON.stringify(err))
    }
  }

  build() {
    Column() {
      Web({
        src: $rawfile("index.html"),
        controller: this.controller
      })
        .width('100%')
        .height('100%')
        .zoomAccess(false)
        .fileAccess(true)
        .domStorageAccess(true)
        .initialScale(100)
    }
    .width('100%')
    .height('100%')
    .backgroundColor(Color.White)
  }
}

4、双网页嵌套Web实现

我把应用程序的Web放在rawfile目录下的index.html中
可以参考我的源码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>底部导航切换</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            touch-action: manipulation;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
            background: #f8f9fa;
            padding-bottom: 80px; /* 为底部导航预留空间 */
        }

        /* 内容区域 */
        .content-container {
            padding: 15px;
            margin-top: 10px;
            transition: all 0.3s;
        }

        #contentFrame {
            width: 100%;
            height: calc(100vh - 140px);
            border: 2px solid #dee2e6;
            border-radius: 16px;
            background: white;
        }

        /* 底部导航栏样式 */
        .nav-bar {
            display: flex;
            gap: 8px;
            padding: 12px;
            background: white;
            box-shadow: 0 -2px 4px rgba(0,0,0,0.08);
            position: fixed;
            bottom: 0;
            left: 0;
            right: 0;
            z-index: 100;
            border-top-left-radius: 24px;
            border-top-right-radius: 24px;
        }

        .nav-btn {
            flex: 1;
            padding: 12px 0;
            border: none;
            border-radius: 24px;
            background: #e9ecef;
            font-size: 16px;
            transition: all 0.3s;
            cursor: pointer;
        }

        .nav-btn:hover {
            background: #007bff;
            color: white;
        }

        .nav-btn.active {
            background: #007bff;
            color: white;
            transform: scale(0.95);
        }

        /* 移动端适配 */
        @media (max-width: 768px) {
            .nav-btn {
                padding: 10px 0;
                font-size: 14px;
            }
            #contentFrame {
                height: calc(100vh - 120px);
            }
            body {
                padding-bottom: 70px;
            }
        }
    </style>
</head>
<body>
<div class="content-container">
    <iframe id="contentFrame" src="https://shazhenyu.blog.csdn.net/" frameborder="0"></iframe>
</div>

<nav class="nav-bar">
    <button class="nav-btn active" onclick="switchTab('csdn')">📝 我的博客</button>
    <button class="nav-btn" onclick="switchTab('baidu')">🔍 手机百度</button>
</nav>

<script>
        function switchTab(target) {
            const frame = document.getElementById('contentFrame');
            const buttons = document.querySelectorAll('.nav-btn');

            // 切换按钮状态
            buttons.forEach(btn => btn.classList.remove('active'));
            event.target.classList.add('active');

            // 切换内容
            const urls = {
                csdn: 'https://shazhenyu.blog.csdn.net/',
                baidu: 'https://m.baidu.com'
            };

            frame.src = urls[target];

            // 特殊页面适配
            if(target === 'csdn') {
                frame.style.height = 'calc(100vh - 140px)';
                document.body.style.backgroundColor = '#f8f9fa';
            } else {
                frame.style.height = 'calc(100vh - 140px)';
                document.body.style.backgroundColor = '#ffffff';
            }
        }

        // 初始化加载CSDN
        window.onload = () => {
            const frame = document.getElementById('contentFrame');
            frame.addEventListener('load', () => {
                // CSDN页面特殊处理
                if(frame.src.includes('csdn.net')) {
                    frame.style.height = 'calc(100vh - 140px)';
                }
            });
        };

        // 窗口尺寸变化处理
        window.addEventListener('resize', () => {
            const frame = document.getElementById('contentFrame');
            frame.style.height = window.innerWidth > 768
                ? 'calc(100vh - 140px)'
                : 'calc(100vh - 120px)';
        });
    </script>
</body>
</html>

5、ArkTS+Web技术架构的演进

相较于传统Web开发模式,ArkTS+Web的融合方案展现出三大优势:

  • 原生性能增强:通过ArkTS声明式UI框架与Web组件的混编,既保留了Web生态的灵活性,又获得了接近原生应用的流畅度
  • 开发效率提升:一套代码同时适配手机、平板等多端设备,相较传统跨平台方案缩减约40%的适配成本
  • 系统级能力接入:可直接调用鸿蒙系统API,实现全屏显示、系统栏控制等原生功能

网站公告

今日签到

点亮在社区的每一天
去签到