鸿蒙ArkTS页面怎样与H5页面交互?

打印 上一主题 下一主题

主题 979|帖子 979|积分 2937

先看效果


功能先容


  • 点击Click Me按钮可以接收展示鸿蒙通报给html的内容
  • 点击霓虹灯按钮可以同步更新底部鸿蒙页面的按钮内容“打开”或“关闭”
  • 点击底部鸿蒙页面的按钮,可以同步修改html的霓虹灯按钮状态
前言

在开辟App时,我们经常会遇到使用webView加载H5页面的场景,这样做的好处就不多加赘述了,那么鸿蒙App怎样加载H5页面呢?又怎么与H5页面进行通讯呢?,废话少说,直接上代码。
通讯功能先容

App可以通过runJavaScript()方法调用html页面的JavaScript相关函数。 在下面的示例中,点击App的“runJavaScript”按钮时,来触发html页面的change()方法更新霓虹灯按钮状态。
html通过鸿蒙的test方法,获取鸿蒙通报过来的数据。通过出发changeBtnText同步更新鸿蒙按钮的内容。
html文件目录:harmonyApp\entry\src\main\resources\rawfile
html代码如下:
  1. <!-- index.html -->
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5.     <meta charset="UTF-8">
  6.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7.     <title>霓虹灯按钮拨动特效</title>
  8.     <style>
  9.         * {
  10.             border: 0;
  11.             box-sizing: border-box;
  12.             margin: 0;
  13.             padding: 0;
  14.         }
  15.         :root {
  16.             --hue: 223;
  17.             --off-hue: 3;
  18.             --on-hue1: 123;
  19.             --on-hue2: 168;
  20.             --fg: hsl(var(--hue), 10%, 90%);
  21.             --primary: hsl(var(--hue), 90%, 50%);
  22.             --trans-dur: 0.6s;
  23.             --trans-timing: cubic-bezier(0.65, 0, 0.35, 1);
  24.             font-size: calc(40px + (60 - 40) * (100vw - 320px) / (2560 - 320));
  25.         }
  26.         body,
  27.         input {
  28.             font: 1em/1.5 sans-serif;
  29.         }
  30.         body {
  31.             background-image: linear-gradient(45deg, hsl(var(--hue), 10%, 20%), hsl(var(--hue), 10%, 10%));
  32.             color: var(--fg);
  33.             display: flex;
  34.             height: 100vh;
  35.             transition: background-color var(--trans-dur), color var(--trans-dur);
  36.         }
  37.         .common{
  38.             height: 6em;
  39.             width: 5em;
  40.         }
  41.         .switch,
  42.         .switch__input {
  43.             -webkit-tap-highlight-color: #0000;
  44.         }
  45.         .switch {
  46.             display: block;
  47.             margin: auto;
  48.             position: relative;
  49.             width: 5em;
  50.             height: 3em;
  51.         }
  52.         .switch__base-outer,
  53.         .switch__base-inner {
  54.             display: block;
  55.             position: absolute;
  56.         }
  57.         .switch__base-outer {
  58.             border-radius: 1.25em;
  59.             box-shadow: -0.125em -0.125em 0.25em hsl(var(--hue), 10%, 30%), 0.125em 0.125em 0.125em hsl(var(--hue), 10%, 30%) inset, 0.125em 0.125em 0.25em hsl(0, 0%, 0%), -0.125em -0.125em 0.125em hsl(var(--hue), 10%, 5%) inset;
  60.             top: 0.125em;
  61.             left: 0.125em;
  62.             width: 4.75em;
  63.             height: 2.75em;
  64.         }
  65.         .switch__base-inner {
  66.             border-radius: 1.125em;
  67.             box-shadow: -0.25em -0.25em 0.25em hsl(var(--hue), 10%, 30%) inset, 0.0625em 0.0625em 0.125em hsla(var(--hue), 10%, 30%), 0.125em 0.25em 0.25em hsl(var(--hue), 10%, 5%) inset, -0.0625em -0.0625em 0.125em hsla(var(--hue), 10%, 5%);
  68.             top: 0.375em;
  69.             left: 0.375em;
  70.             width: 4.25em;
  71.             height: 2.25em;
  72.         }
  73.         .switch__base-neon {
  74.             display: block;
  75.             overflow: visible;
  76.             position: absolute;
  77.             top: 0;
  78.             left: 0;
  79.             width: 100%;
  80.             height: auto;
  81.         }
  82.         .switch__base-neon path {
  83.             stroke-dasharray: 0 104.26 0;
  84.             transition: stroke-dasharray var(--trans-dur) var(--trans-timing);
  85.         }
  86.         .switch__input {
  87.             outline: transparent;
  88.             position: relative;
  89.             width: 100%;
  90.             height: 100%;
  91.             -webkit-appearance: none;
  92.             appearance: none;
  93.         }
  94.         .switch__input:before {
  95.             border-radius: 0.125em;
  96.             box-shadow: 0 0 0 0.125em hsla(var(--hue), 90%, 50%, 0);
  97.             content: "";
  98.             display: block;
  99.             position: absolute;
  100.             inset: -0.125em;
  101.             transition: box-shadow 0.15s linear;
  102.         }
  103.         .switch__input:focus-visible:before {
  104.             box-shadow: 0 0 0 0.125em var(--primary);
  105.         }
  106.         .switch__knob,
  107.         .switch__knob-container {
  108.             border-radius: 1em;
  109.             display: block;
  110.             position: absolute;
  111.         }
  112.         .switch__knob {
  113.             background-color: hsl(var(--hue), 10%, 15%);
  114.             background-image: radial-gradient(88% 88% at 50% 50%, hsl(var(--hue), 10%, 20%) 47%, hsla(var(--hue), 10%, 20%, 0) 50%), radial-gradient(88% 88% at 47% 47%, hsl(var(--hue), 10%, 85%) 45%, hsla(var(--hue), 10%, 85%, 0) 50%), radial-gradient(65% 70% at 40% 60%, hsl(var(--hue), 10%, 20%) 46%, hsla(var(--hue), 10%, 20%, 0) 50%);
  115.             box-shadow: -0.0625em -0.0625em 0.0625em hsl(var(--hue), 10%, 15%) inset, -0.125em -0.125em 0.0625em hsl(var(--hue), 10%, 5%) inset, 0.75em 0.25em 0.125em hsla(0, 0%, 0%, 0.8);
  116.             width: 2em;
  117.             height: 2em;
  118.             transition: transform var(--trans-dur) var(--trans-timing);
  119.         }
  120.         .switch__knob-container {
  121.             overflow: hidden;
  122.             top: 0.5em;
  123.             left: 0.5em;
  124.             width: 4em;
  125.             height: 2em;
  126.         }
  127.         .switch__knob-neon {
  128.             display: block;
  129.             width: 2em;
  130.             height: auto;
  131.         }
  132.         .switch__knob-neon circle {
  133.             opacity: 0;
  134.             stroke-dasharray: 0 90.32 0 54.19;
  135.             transition: opacity var(--trans-dur) steps(1, end), stroke-dasharray var(--trans-dur) var(--trans-timing);
  136.         }
  137.         .switch__knob-shadow {
  138.             border-radius: 50%;
  139.             box-shadow: 0.125em 0.125em 0.125em hsla(0, 0%, 0%, 0.9);
  140.             display: block;
  141.             position: absolute;
  142.             top: 0.5em;
  143.             left: 0.5em;
  144.             width: 2em;
  145.             height: 2em;
  146.             transition: transform var(--trans-dur) var(--trans-timing);
  147.         }
  148.         .switch__led {
  149.             background-color: hsl(var(--off-hue), 90%, 70%);
  150.             border-radius: 50%;
  151.             box-shadow: 0 -0.0625em 0.0625em hsl(var(--off-hue), 90%, 40%) inset, 0 0 0.125em hsla(var(--off-hue), 90%, 70%, 0.3), 0 0 0.125em hsla(var(--off-hue), 90%, 70%, 0.3), 0.125em 0.125em 0.125em hsla(0, 0%, 0%, 0.5);
  152.             display: block;
  153.             position: absolute;
  154.             top: 0;
  155.             left: 0;
  156.             width: 0.25em;
  157.             height: 0.25em;
  158.             transition: background-color var(--trans-dur) var(--trans-timing), box-shadow var(--trans-dur) var(--trans-timing);
  159.         }
  160.         .switch__text {
  161.             overflow: hidden;
  162.             position: absolute;
  163.             width: 1px;
  164.             height: 1px;
  165.         }
  166.         .switch__input:checked~.switch__led {
  167.             background-color: hsl(var(--on-hue1), 90%, 70%);
  168.             box-shadow: 0 -0.0625em 0.0625em hsl(var(--on-hue1), 90%, 40%) inset, 0 -0.125em 0.125em hsla(var(--on-hue1), 90%, 70%, 0.3), 0 0.125em 0.125em hsla(var(--on-hue1), 90%, 70%, 0.3), 0.125em 0.125em 0.125em hsla(0, 0%, 0%, 0.5);
  169.         }
  170.         .switch__input:checked~.switch__base-neon path {
  171.             stroke-dasharray: 52.13 0 52.13;
  172.         }
  173.         .switch__input:checked~.switch__knob-shadow,
  174.         .switch__input:checked~.switch__knob-container .switch__knob {
  175.             transform: translateX(100%);
  176.         }
  177.         .switch__input:checked~.switch__knob-container .switch__knob-neon circle {
  178.             opacity: 1;
  179.             stroke-dasharray: 45.16 0 45.16 54.19;
  180.             transition-timing-function: steps(1, start), var(--trans-timing);
  181.         }
  182.         .btn-box{
  183.             /* width: 2.5em; */
  184.             position: absolute;
  185.             top: 0.1em;
  186.             left: 50%;
  187.             transform: translateX(-50%);
  188.             display: flex;
  189.             flex-direction: column;
  190.             justify-content: center;
  191.             align-items: center;
  192.         }
  193.         .btn-box .btn {
  194.             width: 10em;
  195.             background-color: rgb(32, 93, 224);
  196.             border: none;
  197.             color: white;
  198.             padding: 15px 32px;
  199.             text-align: center;
  200.             text-decoration: none;
  201.             display: inline-block;
  202.             font-size: 0.3em;
  203.             margin: 4px 2px;
  204.             cursor: pointer;
  205.         }
  206.         .btn-box #demo {
  207.             font-size: 0.3em;
  208.         }
  209.     </style>
  210. </head>
  211. <body>
  212.     <div class="btn-box">
  213.         <button class="btn" type="button" onclick="callArkTS()">Click Me!</button>
  214.         <p id="demo"></p>
  215.     </div>
  216.     <label class="switch">
  217.         <input id="switch" class="switch__input" type="checkbox" role="switch">
  218.         <span class="switch__base-outer"></span>
  219.         <span class="switch__base-inner"></span>
  220.         <svg class="switch__base-neon" viewBox="0 0 40 24" width="40px" height="24px">
  221.             <defs>
  222.                 <filter id="switch-glow">
  223.                     <feGaussianBlur result="coloredBlur" stddeviation="1"></feGaussianBlur>
  224.                     <feMerge>
  225.                         <feMergeNode in="coloredBlur"></feMergeNode>
  226.                         <feMergeNode in="SourceGraphic"></feMergeNode>
  227.                     </feMerge>
  228.                 </filter>
  229.                 <linearGradient id="switch-gradient1" x1="0" y1="0" x2="1" y2="0">
  230.                     <stop offset="0%" stop-color="hsl(var(--on-hue1),90%,70%)" />
  231.                     <stop offset="100%" stop-color="hsl(var(--on-hue2),90%,70%)" />
  232.                 </linearGradient>
  233.                 <linearGradient id="switch-gradient2" x1="0.7" y1="0" x2="0.3" y2="1">
  234.                     <stop offset="25%" stop-color="hsla(var(--on-hue1),90%,70%,0)" />
  235.                     <stop offset="50%" stop-color="hsla(var(--on-hue1),90%,70%,0.3)" />
  236.                     <stop offset="100%" stop-color="hsla(var(--on-hue2),90%,70%,0.3)" />
  237.                 </linearGradient>
  238.             </defs>
  239.             <path fill="none" filter="url(#switch-glow)" stroke="url(#switch-gradient1)" stroke-width="1"
  240.                 stroke-dasharray="0 104.26 0" stroke-dashoffset="0.01" stroke-linecap="round"
  241.                 d="m.5,12C.5,5.649,5.649.5,12,.5h16c6.351,0,11.5,5.149,11.5,11.5s-5.149,11.5-11.5,11.5H12C5.649,23.5.5,18.351.5,12Z" />
  242.         </svg>
  243.         <span class="switch__knob-shadow"></span>
  244.         <span class="switch__knob-container">
  245.             <span class="switch__knob">
  246.                 <svg class="switch__knob-neon" viewBox="0 0 48 48" width="48px" height="48px">
  247.                     <circle fill="none" stroke="url(#switch-gradient2)" stroke-dasharray="0 90.32 0 54.19"
  248.                         stroke-linecap="round" stroke-width="1" r="23" cx="24" cy="24"
  249.                         transform="rotate(-112.5,24,24)" />
  250.                 </svg>
  251.             </span>
  252.         </span>
  253.         <span class="switch__led"></span>
  254.         <span class="switch__text">Power</span>
  255.     </label>
  256. </body>
  257. <script>
  258.     let switchDom = document.getElementById("switch");
  259.     function callArkTS() {
  260.         let str = window.harmony.test();
  261.         document.getElementById("demo").innerHTML = '鸿蒙传递过来的参数: '+str;
  262.     }
  263.     switchDom.addEventListener("change", function (e) {
  264.         if(e.target.checked){
  265.             window.harmony.changeBtnText('关闭');
  266.         }else{
  267.             window.harmony.changeBtnText('打开');
  268.         }
  269.     });
  270.     function change() {
  271.         switchDom.checked = !switchDom.checked;
  272.     }
  273. </script>
  274. </html>
复制代码
鸿蒙App代码如下:
  1. // xxx.ets
  2. import web_webview from '@ohos.web.webview';
  3. class WebViewModel {
  4.   btnText: string = '打开';
  5.   constructor() {
  6.   }
  7.   test(): string {
  8.     return 'ArkTS Hello World!';
  9.   }
  10.   // 修改按钮文本
  11.   changeBtnText(value:string){
  12.     this.btnText = value;
  13.   }
  14. }
  15. @Entry
  16. @Component
  17. struct WebComponent {
  18.   webviewController: web_webview.WebviewController = new web_webview.WebviewController();
  19.   // 声明需要注册的对象
  20.   @State vm: WebViewModel = new WebViewModel();
  21.   build() {
  22.     Stack() {
  23.       Column() {
  24.         // 页面内容
  25.         Scroll(){
  26.           Column(){
  27.             // web组件加载本地index.html页面
  28.             Web({ src: $rawfile('index.html'), controller: this.webviewController})
  29.               .domStorageAccess(true)
  30.               .javaScriptAccess(true)
  31.               .onProgressChange((event)=>{
  32.                       // 自行编写加载状态
  33.               })
  34.               // 将对象注入到web端
  35.               .javaScriptProxy({
  36.                 object: this.vm,
  37.                 name: "harmony",
  38.                 methodList: ["test",'changeBtnText'],
  39.                 controller: this.webviewController
  40.               })
  41.           }.padding(16)
  42.         }
  43.         .edgeEffect(EdgeEffect.Fade)
  44.         .width('100%')
  45.         .layoutWeight(1)
  46.         .align(Alignment.TopStart)
  47.         Button(this.vm.btnText)
  48.           .width('80%')
  49.           .borderRadius(10)
  50.           .margin({bottom:px2vp(Number(AppStorage.get('safeAreaTopHeight'))) + ''})
  51.           .onClick(() => {
  52.             if(this.vm.btnText === '打开'){
  53.               this.vm.btnText = '关闭';
  54.             }else if(this.vm.btnText === '关闭'){
  55.               this.vm.btnText = '打开';
  56.             }
  57.             this.webviewController.runJavaScript('change()');
  58.           })
  59.       }
  60.       .height('100%')
  61.       .backgroundColor('#F5F5F5')
  62.     }
  63.   }
  64. }
复制代码
Web组件使用题目

鸿蒙的Web组件加载H5页面会出现很多不测的题目,我这里发起把Web组件的以下两个选项开启,避免题目的产生。

  • domStorageAccess(true)开启文档对象模型存储接口(DOM Storage API)权限
  • javaScriptAccess(true)答应执行JavaScript脚本
具体代码如下:
  1. // xxx.ets
  2. import web_webview from '@ohos.web.webview';
  3. class WebViewModel {
  4.   constructor() {
  5.   }
  6.   test(): string {
  7.     return 'ArkTS Hello World!';
  8.   }
  9. }
  10. @Entry
  11. @Component
  12. struct WebComponent {
  13.   webviewController: web_webview.WebviewController = new web_webview.WebviewController();
  14.   // 声明需要注册的对象
  15.   @State vm: WebViewModel = new WebViewModel();
  16.   build() {
  17.     Column() {
  18.       // web组件加载本地index.html页面
  19.       Web({ src: $rawfile('index.html'), controller: this.webviewController})
  20.               .domStorageAccess(true)
  21.               .javaScriptAccess(true)
  22.         // 将对象注入到web端
  23.         .javaScriptProxy({
  24.           object: this.vm,
  25.           name: "harmony",
  26.           methodList: ["test"],
  27.           controller: this.webviewController
  28.         })
  29.     }
  30.   }
  31. }
复制代码
其他选项可参考 鸿蒙Web官网
Harmony OS NEXT版本(接口及解决方案兼容API12版本或以上版本)


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

农民

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表