HarmonyOS 鸿蒙Next web和js交互的时候只能点击触发交互,没有办法进入就交互

发布于 1周前 作者 songsunli 来自 鸿蒙OS

HarmonyOS 鸿蒙Next web和js交互的时候只能点击触发交互,没有办法进入就交互 web和js交互的时候只能点击触发交互,没有办法进入就交互

2 回复

建议使用下面的方式registerJavaScriptProxy把WebViewJavascriptBridge挂载到window对象,

参考文档

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-webview-V5#registerjavascriptproxy

// JsBridge.ets
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { webview } from '@kit.ArkWeb';
import { contact } from '@kit.ContactsKit';
import { code } from './CodeConstant';
import { JavaScriptItem } from './JavaScriptItem';
import { ParamsItem } from './ParamsItem';
import { call } from '@kit.TelephonyKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { Logger } from './Logger';
import { JSONUtil } from '@pura/harmony-utils/src/main/ets/utils/JSONUtil';
export default class JsBridge {
  controller: webview.WebviewController;
  constructor(controller: webview.WebviewController) {
    this.controller = controller;
  }
  /**
  * 将JavaScript对象注入到窗口中,并调用窗口中的函数。
  *
  * @返回javaScriptProxy对象。
  */
  // get javaScriptProxy(): JavaScriptItem {
  //   let result: JavaScriptItem = {
  //     object: {
  //       // call: this.call
  //     },
  //     name: 'JSBridgeHandle',
  //     methodList: ['call'],
  //     controller: this.controller
  //   }
  //   return result;
  //}
  /**
  * 初始化桥接 // TODO 可以删除
  */
  initJsBridge(): void {
    this.controller.runJavaScript(code);
  }
  registerJavaScriptProxy(): void {
    this.controller.registerJavaScriptProxy({callHandler : (method: string, params: ESObject, callBack: Function) => {
      const paramsObj: ESObject = {
        data: params || null
      }
      this.call(method, JSON.stringify(paramsObj), callBack);}, init: () => {}}, 'WebViewJavascriptBridge', ['callHandler', 'init'] )
    this.controller.refresh();
  }
  /**
  * Use system ability of getting contacts.
  */
  back = (): Promise<string> => {
    let phone = '';
    let name = '';
    return new Promise((resolve) => {
      let promise = contact.selectContacts();
      promise.then((info: Array<contact.Contact>) => {
        info.forEach((item: contact.Contact) => {
          phone = item?.phoneNumbers ? item?.phoneNumbers[0].phoneNumber : '';
          name = item?.name ? item?.name.fullName : '';
        })
      resolve(phone + '_' + name);
      }).catch((err: object | string) => {
        Logger.error(`selectContact fail: err->${JSON.stringify(err)}`);
      });
    })
  }
  makecall = (params: ParamsItem): Promise<string> => {
    Logger.info('手机号', JSON.stringify(params));
    let phone = params.data + '';
    // 调用查询能力接口
    let isSupport = call.hasVoiceCapability();
    if (isSupport) {
      // 如果设备支持呼叫能力,则继续跳转到拨号界面,并显示拨号的号码
      call.makeCall(phone, (err: BusinessError) => {
        if (!err) {
          console.log("make call success.");
        } else {
          console.log("make call fail, err is:" + JSON.stringify(err));
        }
      });
    }
    return new Promise((resolve) => {
      resolve('success');
    })
  }
  getUserInfo = (): Promise<string> => {
    return new Promise(async (resolve) => {
      resolve('{"id":"6592138424979410944","uuid":"0a0b96afbbab4b76b75e898b1de3eb7c","userId":"a9aA/5SXwl067V5Zh9Z+HhjT+A4=","idCardHash":"fliN6XTtBYp2mt21OtUNv34Gr1Q=","name":"褚*军","orgName":"中山东研发中心支部委员会","orgId":"9b5c4ad4-c75e-4b3d-a2bd-e4a5e85fc834","orgCode":"000002000008000001000011000001000002000302000137000002","avatar":"https://uni-oss.dtdjzx.gov.cn/resource-workbanch/uploads/image/2024-06-06/3688603786374287803.jpg","sourceClient":"android","phone":"13402222768","publishMonth":"","examType":"","identity":"PARTY_MEMBER,CADRE,TEACHER,VILLAGE_WORKTEAM"}');
    })
  }
  getToken = (): Promise<string> => {
    return new Promise((resolve) => {
      resolve('a3ffe6a16340305a09485a473db866dde92e7acae772b64e51c2fdcfd1437679fa766887a44e7ab2f2a6a3d64d656bc3453124be329d2f4a54e6de301242d661e57b9f788110cf8864282b85a773d5e4');
    })
  }
  getId = (): Promise<string> => {
    return new Promise((resolve) => {
      let result = '2568623';
      resolve(result);
    })
  }
  /**
  * Invoke the chooseContact function.
  */
  call = (func: string, params: string, callBack: Function): void => {
    const paramsObject: ParamsItem = JSON.parse(params ?? '{}');
    let result: Promise<string> = new Promise((resolve) => resolve(''));
    switch (func) {
      case 'back': //返回
        result = this.back();
        break;
      case 'makecall': //拨号
        result = this.makecall(paramsObject);
        break;
      case 'getToken': //获取用户token
        result = this.getToken();
        break;
      case 'getId': //获取图书资源id
        result = this.getId();
        break;
      case 'getUserInfo': //获取用户信息
        result = this.getUserInfo();
        break;
      default:
        break;
    }
    result.then((data: string) => {
      callBack(data);
    })
  }
  /**
  * The ArkTS invoke the WebView by using runJavaScript. // TODO 可以删除
  */
  callback = (id: number, data: string): void => {
    this.controller.runJavaScript(`JSBridgeCallback('${id}', ${JSON.stringify(data)})`);
  }
}
// Index.ets
import { webview } from '@kit.ArkWeb';
import { JsBridge } from '../view/JsBridge';
@Entry
@Component
struct Index {
  controller: WebviewController = new webview.WebviewController();
  @State url: string = 'https://cms.dtdjzx.gov.cn/digital-library/#/';//图书--调用getId---在调用getUserInfo
  private jsBridge: JsBridge = new JsBridge(this.controller);
  aboutToAppear(): void {
    webview.WebviewController.setWebDebuggingAccess(true);
  }
  build() {
    Column() {
      Web({
        src: '',
        controller: this.controller
      })
      .javaScriptAccess(true)
      .mixedMode(MixedMode.All)
      .onControllerAttached(() => {
        this.jsBridge.registerJavaScriptProxy();
        let userAgent = this.controller.getUserAgent() + "Adr Android android";
        this.controller.setCustomUserAgent(userAgent);
        // 设置完UA之后,再次加载url
        this.controller.loadUrl(this.url)
      })
      .onPageEnd(() => {
      })
      .width('100%')
      .height('100%')
    }
  }
}

更多关于HarmonyOS 鸿蒙Next web和js交互的时候只能点击触发交互,没有办法进入就交互的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS(鸿蒙)系统中,Next web与JavaScript的交互默认可能设计为响应点击事件触发,以实现用户交互的明确性和安全性。如果你希望在页面加载或进入时就自动触发交互,而不是仅限于点击事件,这通常需要对交互逻辑进行一些调整。

鸿蒙系统中,前端页面与JavaScript的交互机制可能依赖于特定的框架或API,这些可能不支持页面加载时的自动交互。要实现进入页面即触发交互,你可能需要:

  1. 检查API文档:查阅鸿蒙系统关于Next web和JavaScript交互的官方API文档,看是否有提供页面加载时触发交互的方法或事件。

  2. 使用生命周期钩子:如果Next web框架支持页面生命周期钩子(如onLoad、onShow等),可以在这些钩子中调用JavaScript函数,以实现页面进入时的自动交互。

  3. 事件模拟:考虑使用JavaScript模拟点击事件,但这通常不是最佳实践,因为它可能绕过了系统的交互设计原则。

如果上述方法仍然无法满足需求,可能是当前鸿蒙系统版本或Next web框架的限制。此时,建议详细阅读鸿蒙系统的更新日志和开发文档,看是否有相关的功能更新或替代方案。

如果问题依旧没法解决请联系官网客服, 官网地址是 https://www.itying.com/category-93-b0.html

回到顶部