HarmonyOS 鸿蒙Next中WebView的H5页面获取元素CSS宽高尺寸与实际设备对应位置尺寸不一致

HarmonyOS 鸿蒙Next中WebView的H5页面获取元素CSS宽高尺寸与实际设备对应位置尺寸不一致

如题,H5页面中,获取某个元素的宽高和位置后,我希望可以通过我定义的JS桥接口,将尺寸和位置传递给ArkTS端,然后ArkTS端生成一个原生View(比如图片或者窗口)覆盖在对应的H5页面的位置上。

但是实际发现,似乎这两边坐标系不太一样。

H5页面中获取到的屏幕宽高:374*843

设备分辨率:1260*2844

1260/374=3.3689839…

这个比例我看不出任何规律,应该如何处理?

补充:

在很久以前,Android4.4时代以前,Android中也存在这个问题,但是Android的WebView中可以获取一个scale,恰好就是这个比例值。后来到了Android4.4之后,scale值似乎永远都是1了。然而现在相同的代码放到鸿蒙这边,这个比例又不是1了。不知道是可以配置什么来调节吗?

H5页面中的viewport配置:

<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width, initial-scale=1, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

更多关于HarmonyOS 鸿蒙Next中WebView的H5页面获取元素CSS宽高尺寸与实际设备对应位置尺寸不一致的实战教程也可以访问 https://www.itying.com/category-93-b0.html

8 回复

同问

更多关于HarmonyOS 鸿蒙Next中WebView的H5页面获取元素CSS宽高尺寸与实际设备对应位置尺寸不一致的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


H5的CSS像素单位与设备物理像素存在DPR换算关系;未进行CSS像素→物理像素→虚拟像素(vp)的二次转换;鸿蒙ArkWeb内核基于Chromium M114,与Android WebView存在行为差差异

楼主修整一下H5侧坐标

<!-- 标准viewport配置需移除target-densitydpi参数 -->

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<script>
// 获取元素实际物理像素尺寸
function getRealRect(element) {
  const dpr = window.devicePixelRatio;
  const rect = element.getBoundingClientRect();
  return {
    x: rect.left * dpr,
    y: rect.top * dpr,
    width: rect.width * dpr,
    height: rect.height * dpr
  };
}
</script>

ArkTS端进行坐标转换

// 物理像素转vp单位
import { display } from '@kit.ArkUI';

const metrics = display.getDefaultDisplaySync();
const density = metrics.density; // 设备像素密度

function px2vp(px: number): number {
  return px / density;
}

// 接收JS桥传递的物理像素坐标
function onH5PositionReceived(rect: {x: number, y: number}) {
  const viewRect = {
    x: px2vp(rect.x),
    y: px2vp(rect.y)
  }
  // 创建覆盖层组件时使用vp单位
  CoverLayer(viewRect)
}

H5页面获取的374x843是鸿蒙系统优化后的逻辑尺寸,而非硬件原生分辨率。

应基于逻辑像素进行布局设计,若需物理像素级操作需通过DPR换算或调用系统API实现

也可以通过JS 获取屏幕的真实分辨率

const dpr = window.devicePixelRatio;
const physicalWidth = Math.round(window.screen.width * dpr);
const physicalHeight = Math.round(window.screen.height * dpr);
  1. 不太建议楼主这样去实现,楼主实现这种效果可以参考一下同层渲染
    同层渲染原生组件-ArkWeb-应用框架 - 华为HarmonyOS开发者

  2. 通过修改js或者同步传递数据、注入JsBridge来实现Web与原生之间的数据、事件交互、涉及到内存的可以将文件存储到沙箱再将地址返回给Web

参考文档:
https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-arkweb_rendering_framework#section1672011288193

  1. H5 页面与 ArkTS 端的尺寸和坐标不一致,主要是因为CSS 像素与物理像素的转换关系以及可能存在的页面缩放导致的

所以,具体如何解决呢,


相关信息:

  • 项目名称: 示例项目
  • 项目状态: 进行中
  • 负责人: 张三
  • 开始时间: 2023-01-01
  • 预计完成时间: 2023-12-31

描述:

这是对项目的简要描述。

鸿蒙Next中WebView的H5页面获取元素尺寸与实际不符,通常因设备像素比(DPR)导致。鸿蒙使用虚拟像素单位vp,H5默认使用CSS像素。解决方案:

  1. 在H5页面添加viewport meta标签:

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    
  2. 使用window.devicePixelRatio校正尺寸

  3. 通过getBoundingClientRect()获取精确尺寸

  4. 在鸿蒙WebView初始化时设置setInitialScale(100)

在HarmonyOS Next中,WebView的H5页面与原生View的尺寸转换问题确实存在,这与设备物理像素、CSS像素和viewport缩放比例相关。以下是关键点分析:

  1. 比例计算问题:
  • 您观察到的3.368比例是设备物理像素(1260x2844)与CSS像素(374x843)的比值,这属于正常现象
  • 这个比例值实际上是设备物理像素与CSS像素的转换系数(devicePixelRatio)
  1. 解决方案建议:
  • 在H5端通过window.devicePixelRatio获取当前设备的像素比
  • 将H5获取的CSS尺寸乘以devicePixelRatio后再传递给ArkTS端
  • 示例代码:
const scale = window.devicePixelRatio;
const realWidth = element.offsetWidth * scale;
const realHeight = element.offsetHeight * scale;
  1. 关于viewport配置:
  • 您当前的配置是正确的
  • target-densitydpi=device-dpi确保了DPI一致性
  • width=device-width确保使用设备宽度作为基准
  1. 原生端处理:
  • ArkTS端接收到的尺寸应该是经过scale换算后的物理像素值
  • 这样原生View的布局才能与H5元素精确对齐

注意:不同设备的devicePixelRatio可能不同,建议每次都动态获取而不是使用固定值。

回到顶部