ArkTS开发系列之Web组件的学习(2.9)

上篇回顾:ArkTS开发系列之事件(2.8.2手势事件)

本篇内容: ArkTS开发系列之Web组件的学习(2.9)

一、知识储备

Web组件就是用来展示网页的一个组件。具有页面加载、页面交互以及页面调试功能

1. 加载网络页面

      Web({ src: this.indexUrl, controller: this.webViewController })

2. 加载本地页面

      Web({ src: $rawfile('local.html'), controller: this.webViewController })

3. 加载html格式的文本数据

  • 该示例中,是点击button后开始加载html格式的文本数据
      Button('加载html文本内容')
        .onClick(event => {
          this.webViewController.loadData(
            "<html><body bgcolor=\"white\">Source:<pre>source</pre></body></html>",
            "text/html",
            "UTF-8"
          );
        })
     
      Web({ src: this.indexUrl, controller: this.webViewController })

4.深色模式设置

      Web({ src: this.indexUrl, controller: this.webViewController })
        .darkMode(WebDarkMode.On) //设置深色模式
        .forceDarkAccess(true)//强制生效

5. 文件上传

      Web({ src: $rawfile('local.html'), controller: this.webViewController })
        .onShowFileSelector(event=>{
        //设置要上传的文件路径
          let fileList: Array<string> =[

          ]
          if (event) {
            event.result.handleFileList(fileList)
          }
          return true;
        })

6. 在新容器中打开页面

  • 通过multiWindowAccess()来设置是否允许网页在新窗口中打开。有新窗口打开时,应用侧会在onWindowNew()接口中收到新窗口事件,需要我们在此接口中处理web组件的窗口请求
.onWindowNew(event=>{
}
  • 如果开发者在onWindowNew()接口通知中不需要打开新窗口,需要将ControllerHandler.setWebController()接口返回值设置成null。

7. 管理位置权限

        .geolocationAccess(true)

8. 应用调用html的js函数

      Web({ src: $rawfile('local.html'), controller: this.webViewController })
        .javaScriptAccess(true)
this.webViewController.runJavaScript('htmlTest()')

9. 前端调用应用函数

  • 在web组件初始化的时候注入javaScriptProxy()
  @State testObj: TestClass = new TestClass(); //注册应用内js调用函数的对象

      Web({ src: $rawfile('local.html'), controller: this.webViewController })
        .javaScriptProxy({//将对角注入到web端
          object: this.testObj,
          name: 'testObjName',
          methodList: ['test'],
          controller: this.webViewController
        })
  • 在web组件初始化完成后注入registerJavaScriptProxy()
 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);

10. 应用与前端页面数据通道

  aboutToAppear() {
    try {
      //1.在这里初始化ports
      this.ports = this.webViewController.createWebMessagePorts();
      this.ports[1].onMessageEvent((result: webview.WebMessage) => { //2.接收消息,并根据业务处理消息
        let msg = '读取网页消息'
        if (typeof (result) == 'string') {
          msg = msg + result;
        } else if (typeof (result) == 'object') {
          if (result instanceof ArrayBuffer) {
            msg = msg + " result length: " + result.byteLength;
          } else {
            console.error('msg not support')
          }
        } else {
          console.error('msg not support')
        }

        this.receiveMsgFromHtml = msg;

        // 3、将另一个消息端口(如端口0)发送到HTML侧,由HTML侧保存并使用。
        this.webViewController.postMessage('__init_port__', [this.ports[0]], "*");
      })
    } catch (err) {
      console.error('err: ' + JSON.stringify(err))
    }
  }


//4.给html发消息
              this.ports[1].postMessageEvent(this.sendFromEts)

11. 管理web组件的页面跳转和浏览记录

  • 返回上一页
          this.controller.backward()
  • 进入下一页
          this.controller.forward()
  • 从web组件跳转到hap应用内的页面
      Web({ controller: this.controller, src: $rawfile('route.html') })
        .onUrlLoadIntercept(event => {
          let url: string = event.data as string;
          if (url.indexOf('native://') === 0) {
            router.pushUrl({ url: url.substring(9) })
            return true;
          }
          return false;
        })
  • 跨应用的页面跳转
            call.makeCall(url.substring(6), err => {
              if (!err) {
                console.info('打电话成功')
              } else {
                console.info('拨号失败' + JSON.stringify(err))
              }
            })

12. 管理Cookie及数据存储

Cookie信息保存在应用沙箱路径下/proc/{pid}/root/data/storage/el2/base/cache/web/Cookiesd的文件中。
由WebCookieManager管理cookie

      webview.WebCookieManager.setCookie('https://www.baidu.com','val=yes') //存储cookie
  • 四种缓存策略(Cache)
    Default : 优先使用未过期的缓存,如果缓存不存在,则从网络获取。
    None : 加载资源使用cache,如果cache中无该资源则从网络中获取。
    Online : 加载资源不使用cache,全部从网络中获取。
    Only :只从cache中加载资源。
  • 清除缓存
this.controller.removeCache(true);
  • 是否持久化缓存domStorageAccess
domStorageAccess(true) ///true是Local Storage持久化存储;false是Session Storage,会随会话生命周期释放

13. 自定义页面请求响应

通过对onIntercerptRequest接口来实现自定义

        .onInterceptRequest((event?: Record<string, WebResourceRequest>): WebResourceResponse => {

          if (!event) {
            return new WebResourceResponse();
          }
          let mRequest: WebResourceRequest = event.request as WebResourceRequest;

          console.info('url: ' + mRequest.getRequestUrl())
          if (mRequest.getRequestUrl().indexOf('https://www.baidu.com') === 0) {
            this.responseResource.setResponseData(this.webdata)
            this.responseResource.setResponseEncoding('utf-8')
            this.responseResource.setResponseMimeType('text/html')
            this.responseResource.setResponseCode(200);
            this.responseResource.setReasonMessage('OK')
            return this.responseResource;
          }
          return;
        })

14.

  • 第一步
  aboutToAppear() {
    // 配置web开启调试模式
    web_webview.WebviewController.setWebDebuggingAccess(true);
  }
  • 第二步
// 添加映射 
hdc fport tcp:9222 tcp:9222 
// 查看映射 
hdc fport ls
  • 第三步
在电脑端chrome浏览器地址栏中输入chrome://inspect/#devices,页面识别到设备后,就可以开始页面调试。

二、 效果一览

在这里插入图片描述

三、 源码大杂烩

import webview from '@ohos.web.webview'
import router from '@ohos.router';
import call from '@ohos.telephony.call';

@Entry
@Component
struct Index {
  controller: webview.WebviewController = new webview.WebviewController();
  responseResource: WebResourceResponse = new WebResourceResponse();
  @State webdata: string = "<!DOCTYPE html>\n" +
  "<html>\n" +
  "<head>\n" +
  "<title>将www.baidu.com改成我</title>\n" +
  "</head>\n" +
  "<body>\n" +
  "<h1>将www.baidu.com改成我</h1>\n" +
  "</body>\n" +
  "</html>"

  build() {
    Column() {
      Button('上一页')
        .onClick(() => {
          this.controller.backward()
        })

      Button('下一页')
        .onClick(() => {
          this.controller.forward()
        })

      Web({ controller: this.controller, src: 'www.baidu.com' })
        // Web({ controller: this.controller, src: $rawfile('route.html') })
        .onUrlLoadIntercept(event => {
          let url: string = event.data as string;
          if (url.indexOf('native://') === 0) {
            router.pushUrl({ url: url.substring(9) })
            return true;
          } else if (url.indexOf('tel://') === 0) {
            call.makeCall(url.substring(6), err => {
              if (!err) {
                console.info('打电话成功')
              } else {
                console.info('拨号失败' + JSON.stringify(err))
              }
            })
            return true;
          }
          return false;
        })
        .onInterceptRequest((event?: Record<string, WebResourceRequest>): WebResourceResponse => {

          if (!event) {
            return new WebResourceResponse();
          }
          let mRequest: WebResourceRequest = event.request as WebResourceRequest;

          console.info('url: ' + mRequest.getRequestUrl())
          if (mRequest.getRequestUrl().indexOf('https://www.baidu.com') === 0) {
            this.responseResource.setResponseData(this.webdata)
            this.responseResource.setResponseEncoding('utf-8')
            this.responseResource.setResponseMimeType('text/html')
            this.responseResource.setResponseCode(200);
            this.responseResource.setReasonMessage('OK')
            return this.responseResource;
          }
          return;
        })

      // webview.WebCookieManager.setCookie('https://www.baidu.com','val=yes')
    }
    .width('100%')
    .height('100%')
  }
}
import webview from '@ohos.web.webview';
import common from '@ohos.app.ability.common';
import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
import geoLocationManager from '@ohos.geoLocationManager';

let context = getContext(this) as common.UIAbilityContext;
let atManager = abilityAccessCtrl.createAtManager();
try {
  atManager.requestPermissionsFromUser(context, ["ohos.permission.LOCATION", "ohos.permission.APPROXIMATELY_LOCATION"], (err, data) => {
    // let requestInfo: geoLocationManager.LocationRequest = {
    //   'priority': 0x203,
    //   'scenario': 0x300,
    //   'maxAccuracy': 0
    // };
    //
    // let locationChange = (location: geoLocationManager.Location): void => {
    //   if (location) {
    //     console.error('location = ' + JSON.stringify(location))
    //   }
    // };
    //
    // try {
    //   geoLocationManager.on('locationChange', requestInfo, locationChange);
    //   geoLocationManager.off('locationChange', locationChange);
    // } catch (err) {
    //   console.error('err : ' + JSON.stringify(err))
    // }
    console.info('data: ' + JSON.stringify(data))
    console.info("data permissions: " + JSON.stringify(data.permissions))
    console.info("data authResults: " + JSON.stringify(data.authResults))
  }
  )
} catch (err) {
  console.error('err : ', err)
}

class TestClass {
  constructor() {
  }

  test() {
    return '我是应用内函数';
  }
}

@Entry
@Component
struct Index {
  @State indexUrl: string = 'www.baidu.com';
  webViewController: webview.WebviewController = new webview.WebviewController();
  dialog: CustomDialogController | null = null
  @State testObj: TestClass = new TestClass(); //注册应用内js调用函数的对象

  ports: webview.WebMessagePort[]; //消息端口

  @State sendFromEts: string = '这消息将被发送到html'
  @State receiveMsgFromHtml: string = '这将展示接收到html发来的消息'

  aboutToAppear() {
    try {
      //1.在这里初始化ports
      this.ports = this.webViewController.createWebMessagePorts();
      this.ports[1].onMessageEvent((result: webview.WebMessage) => { //2.接收消息,并根据业务处理消息
        let msg = '读取网页消息'
        if (typeof (result) == 'string') {
          msg = msg + result;
        } else if (typeof (result) == 'object') {
          if (result instanceof ArrayBuffer) {
            msg = msg + " result length: " + result.byteLength;
          } else {
            console.error('msg not support')
          }
        } else {
          console.error('msg not support')
        }

        this.receiveMsgFromHtml = msg;

        // 3、将另一个消息端口(如端口0)发送到HTML侧,由HTML侧保存并使用。
        this.webViewController.postMessage('__init_port__', [this.ports[0]], "*");
      })
    } catch (err) {
      console.error('err: ' + JSON.stringify(err))
    }
  }

  build() {
    Column() {
      Button('加载html文本内容')
        .onClick(event => {
          this.webViewController.loadData(
            "<html><body bgcolor=\"white\">Source:<pre>source</pre></body></html>",
            "text/html",
            "UTF-8"
          );
        })
      Button('调用html的js函数')
        .onClick(event => {
          this.webViewController.runJavaScript('htmlTest()')
        })
      Button('web组件初始化完成后注入')
        .onClick(event => {
          this.webViewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test"]);
        })
      Text(this.receiveMsgFromHtml).fontSize(33)
      Button('给html端发消息')
        .onClick(() => {
          try {
            if (this.ports && this.ports[1]) {
              //4.给html发消息
              this.ports[1].postMessageEvent(this.sendFromEts)
            } else {
              console.error('ports init fail')
            }
          } catch (err) {
            console.error('ports init fail ' + JSON.stringify(err))
          }
        })

      // Web({ src: this.indexUrl, controller: this.webViewController })
      //   .darkMode(WebDarkMode.On) //设置深色模式
      //   .forceDarkAccess(true) //强制生效
      // Web({ src: $rawfile('window.html'), controller: this.webViewController })
      //   .javaScriptAccess(true)
      //   .multiWindowAccess(true)
      //   .onWindowNew(event=>{
      //     if (this.dialog) {
      //       this.dialog.close()
      //     }
      //
      //     let popController: webview.WebviewController = new webview.WebviewController();
      //
      //     this.dialog = new CustomDialogController({
      //       builder: NewWebViewComp({webviewController1: popController})
      //     })
      //     this.dialog.open()
      //     //将新窗口对应WebviewController返回给Web内核。
      //     //如果不需要打开新窗口请调用event.handler.setWebController接口设置成null。
      //     //若不调用event.handler.setWebController接口,会造成render进程阻塞。
      //     event.handler.setWebController(popController)
      //   })

      Web({ src: $rawfile('postMsg.html'), controller: this.webViewController })

      // Web({ src: $rawfile('local.html'), controller: this.webViewController })
      //   .onShowFileSelector(event => {
      //     //设置要上传的文件路径
      //     let fileList: Array<string> = []
      //     if (event) {
      //       event.result.handleFileList(fileList)
      //     }
      //     return true;
      //   })
      //   .geolocationAccess(true)
      //   .javaScriptAccess(true)
      //   .javaScriptProxy({//将对角注入到web端
      //     object: this.testObj,
      //     name: 'testObjName',
      //     methodList: ['test'],
      //     controller: this.webViewController
      //   })
      //   .onGeolocationShow(event => {
      //     AlertDialog.show({
      //       title: '位置权限请求',
      //       message: '是否允许获取位置信息',
      //       primaryButton: {
      //         value: '同意',
      //         action: () => {
      //           event.geolocation.invoke(event.origin, true, false);
      //         }
      //       },
      //       secondaryButton: {
      //         value: '取消',
      //         action: () => {
      //           if (event) {
      //             event.geolocation.invoke(event.origin, false, false)
      //           }
      //         }
      //       },
      //       cancel: () => {
      //         if (event) {
      //           event.geolocation.invoke(event.origin, false, false)
      //         }
      //       }
      //
      //     })
      //   })
    }
    .width('100%')
    .height('100%')
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/746956.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Java】Java序列化和反序列化

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 # Java中的序列化和反序列化 在Java中&#xff0c;序列化是将对象的状态写入字节流的机制。它主要用于Hibernate…

国家自然科学基金标书大全(2002-2024)

数据来源&#xff1a;在20世纪80年代初&#xff0c;为了促进中国的科技体制革新并改革科研资金分配机制&#xff0c;中国科学院的89位院士联名向党和国家领导人提出建议&#xff0c;设立了国家自然科学基金的设立。国自然基金自创立以来&#xff0c;根据国家发展科学技术方针、…

可以一键生成热点营销视频的工具,建议收藏

在当今的商业环境中&#xff0c;热点营销已经成为了一种非常重要的营销策略。那么&#xff0c;什么是热点营销呢&#xff1f;又怎么做热点营销视频呢&#xff1f; 最近高考成绩慢慢公布了&#xff0c;领导让结合“高考成绩公布”这个热点&#xff0c;做一个关于企业或产品的营销…

力扣:59. 螺旋矩阵 II(Java,模拟)

目录 题目描述示例 1&#xff1a;代码实现 题目描述 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;[[1,2,3],[8,9,4],[7,6,5…

想布局短视频赛道,云微客AI矩阵系统告诉你诀窍

随着人工智能技术的不断发展&#xff0c;越来越多的企业和个人创作者开始意识到智能化的重要性。而现阶段&#xff0c;随着短视频市场的膨胀扩大&#xff0c;批量成片、智能创作、定时发布是当下重要的趋势&#xff0c;企业如果想在短视频赛道分一杯羹&#xff0c;智能化的平台…

七天速通javaSE:第二天 基础:标识符与数据类型

文章目录 前言一、注释与标识符1. 注释2. 标识符2.1 标识符2.2 关键字 二、数据类型1. 语言类型2. 数据类型2.1 基本数据类型2.2引用数据类型 三、类型转换1. 自动转换2. 强制转换&#xff08;不建议&#xff09; 四、代码规范 前言 今天将学习Java语法的基础&#xff0c;认识…

自然语言处理——英文文本预处理

高质量数据的重要性 数据的质量直接影响模型的性能和准确性。高质量的数据可以显著提升模型的学习效果&#xff0c;帮助模型更准确地识别模式、进行预测和决策。具体原因包括以下几点&#xff1a; 噪音减少&#xff1a;高质量的数据经过清理&#xff0c;减少了无关或错误信息…

open()函数——打开文件并返回文件对象

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 open()函数用于打开文件&#xff0c;返回一个文件读写对象&#xff0c;然后可以对文件进行相应读写操作。 语法参考 open()函数的语法格式如下&…

Vite响应Ajax请求

Vite响应Ajax请求 陈拓 2024/06/20-2024/06/24 1. 概述 http-server、live-server 等常用于本地测试和开发的http服务器不能很好的支持 ES 模块&#xff0c;在测试ES 模块时浏览器控制台经常显示错误&#xff1a; Failed to load module script: Expected a JavaScript modu…

【TOOL】ceres学习笔记(二) —— 自定义函数练习

文章目录 一、曲线方程1. 问题描述2. 实现方案 一、曲线方程 1. 问题描述 现有数学模型为 f ( x ) A e x B s i n ( x ) C x D f(x)Ae^xBsin(x)Cx^D f(x)AexBsin(x)CxD &#xff0c;但不知道 A A A 、 B B B 、 C C C 、 D D D 各参数系数&#xff0c;实验数据中含有噪声…

llm-universe | 四. 构建RAG应用

构建RAG应用 一.将LLM 接入 LangChain二.构建检索问答链1.加载向量数据库2.创建一个 LLM3.构建检索问答链4.检索问答链效果测试5.添加历史对话的记忆功能5.1 记忆&#xff08;Memory&#xff09;5.2 对话检索链&#xff08;ConversationalRetrievalChain&#xff09; 三. 部署知…

11-Django项目--Ajax请求二

目录 模版: demo_list.html perform_list.html 数据库操作: 路由: 视图函数: Ajax_data.py perform.py 模版: demo_list.html {% extends "index/index.html" %} {% load static %} # 未实现修改,删除操作{% block content %}<div class"container…

基于YOLOv8的多端车流检测系统(用于毕设+开源)

目录 ✨基于YOLOv8&#x1f680;的多端车流检测系统-MTAS (Multi-Platform Traffic Analysis System) 一、基本功能介绍 1、客户端 &#xff08;pyside6yolov8pytorch&#xff09; 2、网页端&#xff08;Vue3TypestriptPython3MySQL&#xff09; 3、创新点&#xff08;毕设需…

2024年最新通信安全员考试题库

61.架设架空光缆&#xff0c;可使用吊板作业的情况是&#xff08;&#xff09;。 A.在2.2/7规格的电杆与墙壁之间的吊线上&#xff0c;吊线高度5m B.在2.2/7规格的墙壁与墙壁之间的吊线上&#xff0c;吊线高度6m C.在2.2/7规格的电杆与电杆之间的吊线上&#xff0c;吊线高度…

【嵌入式 RT-Thread】一种优雅的使用 [互斥锁] 和 [信号量] 解决数据多路并发思路

rt-thread 中的信号量和互斥锁在工业开发项目中的应用&#xff0c;本博文主要介绍了一种优雅的使用 [互斥锁] 和 [信号量] 解决数据多路并发思路 2024-06 by 积跬步、至千里 目录 0. 个人简介 && 授权须知1. 工业场景描述1.1 工业数据采集需求1.2 总线协议与数据采集 2…

杭州代理记账报税全程托管专业实力全面指南

杭州代理记税报税服务可以为企业提供全程托管财务管理解决方案&#xff0c;确保企业的财务工作专业、高效、合规。以下是杭州代理记税报税服务全面指南&#xff1a; https://www.9733.cn/news/detail/185.html 一、代理记账报税服务的内容 基础服务&#xff1a; 每日记&#xf…

昇思25天学习打卡营第3天|张量Tensor

认识张量 张量&#xff0c;是一个数据结构&#xff0c;也可以说是一个函数&#xff0c;它描述了标量、矢量和张量之间线性关系。这些关系包括 内积、外积、线性映射以及笛卡尔积。张量中既有大小、又有方向。张量由多个数值构成&#xff0c;在n维空间里&#xff0c;会出现 n …

java对word文档预设参数填值并生成

目录 &#xff08;1&#xff09;定义word文档模板 &#xff08;2&#xff09;模板二次处理 处理模板图片&#xff0c;不涉及图片可以跳过 处理模板内容 &#xff08;3&#xff09;java对word模板填值 &#xff08;4&#xff09;Notepad的XML Tools插件安装 工作上要搞一个…

Yolo v5实现细节(2)

Yolo v5代码实现细节 IOU系列损失 在之前的yolo v3中我们使用的定位损失主要使用的是差值平方的形式&#xff0c;通过预测边界框的参数和真实边界框的参数来进行计算求解的。 定位损失 L loc ( t , g ) ∑ i ∈ pos ( σ ( t x i ) − g ^ x i ) 2 ( σ ( t y i ) − g ^ …

c语言学习记录(十)———函数

文章目录 前言一、函数的基本用法二、函数的参数传递1.基本方式2 数组在函数中的传参 前言 一个学习C语言的小白~ 有问题评论区或私信指出~ 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、函数的基本用法 函数是一个完成特定功能的代码模块&…