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

news2024/10/6 20:30:41

上篇回顾: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%')
  }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多商户万能DIY商城小程序源码系统 支持自营+独立部署 带完整的安装代码包以及搭建教程

系统概述 多商户万能 DIY 商城小程序源码系统是一个综合性的电商平台解决方案&#xff0c;旨在满足不同用户的多样化需求。它不仅支持自营模式&#xff0c;还为多商户入驻提供了广阔的空间&#xff0c;使平台能够汇聚各类商品和商家&#xff0c;形成一个丰富多样的商业生态。 …

字节发布Depth Anything V2深度模型,比 Depth Anything V1 更精细的细节。

欢迎点击关注下方公众号并加入官方读者交流群&#xff0c;一个有趣有AI的AIGC公众号:关注AI、深度学习、计算机视觉、AIGC、Stable Diffusion、Sora等相关技术&#xff0c;欢迎一起交流学习&#x1f497;&#xff5e; 字节发布Depth Anything V2深度模型。比 Depth Anything V1…

昇思25天学习打卡营第3天|onereal

前几天不能运行代码&#xff0c;经过排查是因为我的浏览器是搜狗的&#xff0c;换成Chrome问题解决了。按照提示学习了《应用实践/计算机视觉/FCN图像语义分割.ipynb》并且尝试运行代码&#xff0c;开始训练&#xff0c;最后看到图片变化。 网络流程 FCN网络的流程如下图所示&…

【课程总结】Day11(下):YOLO的入门使用

前言 YOLO的简介 YOLO&#xff08;You Only Look Once&#xff09;是一种流行的目标检测算法&#xff0c;由Joseph Redmon等人于2015年提出。YOLO的设计思想是将目标检测任务转化为单个神经网络的回归问题&#xff0c;通过在图像上划分网格并对每个网格预测边界框和类别置信度…

Node.js全栈指南:浏览器显示一个网页

上一章&#xff0c;我们了解到&#xff0c;如何通过第二章的极简 Web 的例子来演示如何查看官方文档。为什么要把查阅官方文档放在前面的章节说明呢&#xff1f;因为查看文档是一个很重要的能力&#xff0c;就跟查字典一样。 回想一下&#xff0c;我们读小学&#xff0c;初中的…

如何创建一个vue项目

目录 1.环境准备 2.检查node和npm版本&#xff0c;确定已安装nodejs 3.全局安装vue/cli、webpack、webpack-cli、vue/cli-init 4.检查vue版本,注意V是大写 5.创建vue项目 6.得到的vue项目目录结构如下&#xff1a; 1.环境准备 安装nodejs,或者安装nvm&#xff0c;并使用…

day38动态规划part01| 理论基础 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

**理论基础 ** 无论大家之前对动态规划学到什么程度&#xff0c;一定要先看 我讲的 动态规划理论基础。 如果没做过动态规划的题目&#xff0c;看我讲的理论基础&#xff0c;会有感觉 是不是简单题想复杂了&#xff1f; 其实并没有&#xff0c;我讲的理论基础内容&#xff0c;…

盲源信道分离—FastICA算法性能仿真

本案例中使用Matlab软件对FastICA算法的声音分离性能进行了仿真&#xff0c;分别对简单波形的混合信号、不同类型声音的混合信号、同一类型的混合信号这三种情况进行仿真&#xff0c;主要从分离信号的波形形状、串音误差两方面对分离性能进行衡量&#xff0c;仿真结果显示快速I…

前端新手小白的第一个AI全栈项目---AI聊天室

前言 ok&#xff0c;大家好。- ̗̀(๑ᵔ⌔ᵔ๑)最近也是想做自己的第一个前后端分离的项目&#xff0c;刚好最近学了一点AI接口的实现。想着用接口做一个自己的ai聊天室并且尝试一下全栈式开发。中间真的解决了很多问题&#xff0c;也是成功之后也是想要将实现过程分享一下&a…

4.任务调度

1.基本知识 2.任务的状态 FreeRTOS中任务共存在4种状态&#xff1a;Running 运行态 当任务处于实际运行状态称之为运行态&#xff0c;即CPU的使用权被这个任务占用&#xff08;同一时间仅一个任务处于运行态&#xff09;。Ready 就绪态 处于就绪态的任务是指那些能够运行&…

6毛钱SOT-23封装28V、400mA 开关升压转换器,LCD偏置电源和白光LED应用芯片TPS61040

SOT-23-5 封装 TPS61040 丝印PHOI 1 特性 • 1.8V 至 6V 输入电压范围 • 可调节输出电压范围高达 28V • 400mA (TPS61040) 和 250mA (TPS61041) 内部开关电流 • 高达 1MHz 的开关频率 • 28μA 典型空载静态电流 • 1A 典型关断电流 • 内部软启动 • 采用 SOT23-5、TSOT23…

图解HTTP笔记整理(前六章)

图解HTTP 第一章 web使用HTTP &#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;协议作文规范&#xff0c;完成从客户端到服务器端等一系列运作流程。 协议&#xff1a;计算机与网络设备要相互通信&#xff0c;双方就必须基于相同的方法。比如…

[油猴脚本] Image To Ascii 快速转换审计网站图片中敏感信息插件

项目地址:https://github.com/MartinxMax/ImageToAscii 导入 将ImagetoAscii.user.js导入油猴 进行按照 访问网站分析图片 当鼠标靠近图片时会出现分析按钮 通过审查图片信息,我们可以快速发现这张图片存在PHP代码。 当然在渗透测试中,你可以快速查看上传的图片木马中PHP代码…

经验分享,在线word转图片

这里分享一个在线word转图片的网站&#xff0c;比较好用 网址&#xff1a;http://www.docpe.com/word/word-to-image.aspx 截图&#xff1a;

40.连接假死-空闲检测-发送心跳

连接假死情况 1.网络设备出现故障,例如网卡,机房等。底层的TCP连接已经断开,但应用程序没有感知到,仍然占着资源。 2.公网网络不稳定,出现丢包。若果连续出现丢包,这时现象就是客户端数据发不出去,服务端也一直收不到数据,就这么一直耗着。 3.应用程序线程阻塞,无法…

甲子光年专访天润融通CEO吴强:客户经营如何穿越低速周期?

作者&#xff5c;陈杨、编辑&#xff5c;栗子 社会的发展从来都是从交流和联络开始的。 从结绳记事到飞马传信&#xff0c;从电话电报到互联网&#xff0c;人类的联络方式一直都在随着时代的发展不断进步。只是传统社会通信受限于技术导致效率低下&#xff0c;对经济社会产生影…

浅谈 MySQL 复制架构

Author&#xff1a;Arsen Date&#xff1a;2024/06/26 目录 前言一、参数设置1.1 slave_exec_mode1.2 max_allowed_packet1.3 binlog-do-db1.4 binlog-ignore-db1.5 replicate-ignore-db1.6 replicate-ignore-table1.7 replicate-wild-ignore-table1.8 slave_compressed_protoc…

实时美颜技术解析:视频美颜SDK如何改变直播行业

实时美颜技术的出现&#xff0c;尤其是视频美颜SDK的应用&#xff0c;正逐渐改变着直播行业的生态。 一、实时美颜技术的原理 实时美颜技术利用人工智能和图像处理算法&#xff0c;对视频中的人物面部进行优化和修饰。该技术通常包含以下几个步骤&#xff1a; 1.人脸检测和识…

ue 材质贴图Tiling repeat

材质问题&#xff0c;如下 贴图显然不符合逻辑&#xff0c;太大&#xff0c;并且是一次性贴图 换一个红砖纹理&#xff0c;就看清了&#xff0c;砖太大了 修改&#xff1a; 拖出一个TexCoord&#xff0c;代表坐标&#xff0c;拖出一个参数&#xff0c;代表次数&#xff0c;如…

AI自动生成角色和情节连续的漫画,中山大学联想提出AutoStudio,可以多轮交互式连续生成并保持主题一致性。

中山大学和联想研究院提出AutoStudio: 是一种无需训练的多代理框架&#xff0c;用于多轮交互式图像生成&#xff0c;能够在生成多样化图像的同时保持主体一致性。 AutoStudio 采用三个基于 LLM 的智能体来解释人类意图并为 SD 模型生成适当的布局指导。此外&#xff0c;还引入…