高德地图在webapp中如何适配rem?
问题
就目前所知高德和百度地图并没有为rem单位提供适配方法。看到此处不要急,且让我慢慢道来!
我在项目中使用的是淘宝flexible适配rem的方案,原本是适配dpr分别是1、2、3的情况下,但是在dpr=3时,地图文字太小。
然后看到高德地图在使用时有font-size设置。内心有些happy,企图利用font-size来适配。but...然并卵,我使用无比大的font-size都没有撼动它!
此时我已经用高德地图实现了一些功能,深陷此坑,只能继续蹲下去

仔细观察一下发现dpr=2的时候地图大小最适宜。按照指示设置了dpr=2。
具体实现
html
1.首先在HTML标签中加上
data-dpr="2"
<html style="width:100%;height:100%;overflow:hidden;" data-dpr="2">
2.然后加<meta>标签
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
此处注意, 不要加❌width=device-width。
又出现问题!!
在安卓机上webview被放大,页面变大!
首先讲一下原因,在iPhone中,meta标签中不加width时,它是retina屏,宽度是单倍宽度width*dpr,例如iPhone6就是375*dpr。但是安卓不是。
解决方法
- 计算实际dpr
function testDpr() {
var realdpr;
var isAndroid = win.navigator.appVersion.match(/android/gi);
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if(isIPhone||isAndroid) {
// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
if(devicePixelRatio >= 3 && (!realdpr || realdpr >= 3)) {
realdpr = 3;
} else if(devicePixelRatio >= 2 && (!realdpr || realdpr >= 2)) {
realdpr = 2;
} else {
realdpr = 1;
}
} else {
// 其他设备下,仍旧使用1倍的方案
realdpr = 1;
}
return realdpr;
}
2.设置安卓的width。由于width = docEl.getBoundingClientRect().width获取的安卓屏幕尺寸不准确(手机明明是1080得到的却是980),此处我选择固定宽度720,也可以根据实际尺寸判断使用640、720或其他尺寸。
function refreshRem() {
var width = docEl.getBoundingClientRect().width;//对于iOS直接可获得实际宽度
if(width / dpr > 540) { width = 540 * dpr; } var isAndroid = win.navigator.appVersion.match(/android/gi); if(isAndroid){ width = 720;//或者width=width/testDpr()*dpr metaEl.setAttribute("content",'width=' + width + ', initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no')//安卓则要自己设置width } var rem = width / 10; docEl.style.fontSize = rem + 'px'; flexible.rem = win.rem = rem; }其实也可以直接设置meta使width=device-width,不过加载时屏幕会晃动。
高德地图图标大小
地图标注图标大小是没有办法改变的,它是直接写在标签内的,无法覆盖。但是高德地图UI组件样式是可以改的,使用rem后UI组件看起来比较小,可以打开chrome浏览器去看控制元素,直接覆盖样式。代码参考如下:
#map {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
font-size: 12px; }
.amap-ui-control-zoom a {
font-size: 17px; }
[data-dpr="2"] .amap-ui-control-zoom a {
font-size: 34px; }
[data-dpr="3"] .amap-ui-control-zoom a {
font-size: 51px; }
#map .amap-ui-control-zoom a, #map .amap-ui-mobile .amap-ui-control-zoom a {
width: 32px;
height: 36px;
line-height: 36px; }
[data-dpr="2"] #map .amap-ui-control-zoom a, [data-dpr="2"] #map .amap-ui-mobile .amap-ui-control-zoom a {
width: 64px;
height: 72px;
line-height: 72px; }
[data-dpr="3"] #map .amap-ui-control-zoom a, [data-dpr="3"] #map .amap-ui-mobile .amap-ui-control-zoom a {
width: 96px;
height: 108px;
line-height: 108px; }
#map .amap-ui-control-zoom, #map .amap-ui-mobile .amap-ui-control-zoom {
width: 32px;
height: 72px; }
[data-dpr="2"] #map .amap-ui-control-zoom, [data-dpr="2"] #map .amap-ui-mobile .amap-ui-control-zoom {
width: 64px;
height: 144px; }
[data-dpr="3"] #map .amap-ui-control-zoom, [data-dpr="3"] #map .amap-ui-mobile .amap-ui-control-zoom {
width: 96px;
height: 216px; }
#map .amap-ui-control-position-rm {
right: 0.26667rem; }