关于viewport引起的微信二维码识别区域偏移的问题讨论与解决

一、问题概述

在开发一个含有二维码的微信页面时,我遇到了这样一个问题:使用iPhone第一次进入该页面时,二维码可以长按识别,但第二次进入时长按无法识别到二维码。安卓机都能识别。

二、我进行了以下尝试:

  1. 移除控制进入条件的脚本,即部分第一次第二次,长按不能识别二维码。暂时排除脚本原因。

  2. 移除二维码所有样式,发现并不是不能识别到二维码而是识别区域发生了偏移。(图1)

  3. 移除所有元素,页面上只留一张二维码,发现识别区域变大。虽然整张图都被识别了但图片外面的区域也会被识别。(图2)

图1

图2
阶段性结论:二维码能被长按识别,但因为某种原因识别区域发生了偏移。

三、进一步尝试:

在网上简单搜索了偏移问题后,我注意到一条关于<meta>标签的,大意如下:

meta标签定义了默认缩放为一倍就能识别,不定义就不能识别。于是我将原来的

<meta name="viewport" content="target-densitydpi=device-dpi, user-scalable=no">

改成了

<meta name="viewport" content="user-scalable=no,width=device-width,initial-scale=1,maximum-scale=1">

虽然样式飞了但二维码识别正常了。
看来问题就出在这里了。经过尝试,我发现:
target-densitydpi=device-dpi和width=device-width是冲突的。加上后者二维码识别正常了,但样式肯定要重新定义,若不加,样式好使,但二维码识别就不正常了。定义样式是小事,但归根结底,发生偏移的原因到底在哪呢?

四、分析

  • 关于适配屏幕的<meta name="viewport">标签

UI设计人员都知道因为pc和移动设备屏幕密度像素的不同在输出视觉稿的时候要标明空间的倍数大小,所谓的@1x、@2x就是这个原因。然后在页面head里写这样一个<meta>标签:

<meta name="viewport" content="user-scalable=no,width=device-width,initial-scale=1,maximum-scale=1">

即:宽度强制转换成设备宽度,默认缩放比例为1,最大缩放比例1,不允许手动缩放。
比如按照iPhone6出的设计稿,在开发的时候空间尺寸就要除以2,iPhone6 plus出的设计稿,尺寸就除以3。具体原理请看图3
但是如果不想进行单位换算,可以用

<meta name="viewport" content="target-densitydpi=device-dpi, user-scalable=no">

即:分辨率转为设备分辨率……(后边都一样)
强制将搭建好的页面适应移动设备的分辨率。原理就好比是将大尺寸的图片缩小显示并不影响清晰度。
这样给设计和前端开发人员都带来很大的方便。既不用设计出标注,也不用切两套控件出来了。

  • 由此产生的问题和猜测

问题就是元素偏移了。。。但我猜测应该是这样的:可视的页面呗强制“塞”到手机屏幕里,但页面本身仍然是原始大小的(图4)。这样看来,并不是触控区域偏移了而是,可视区域被我们“塞到”了移动设备里。发生偏移的实际上是我们看到的那部分。


图3


图4

五、问题的解决

找到了这个原因,剩下的就是老老实实的,按照实际尺寸修改css了,将所有定义了固定尺寸的元素的宽高,包括字体都除以2,保留所有百分比定义的尺寸。哪里不对改哪里,工作量着实不小。这样搭建出来的页面就是实际大小的,没有经过任何缩放,图片该在哪就是在哪不会有偏移了。

六、不能解释的问题

  1. 为什么该问题只有iPhone存在,或许是因为识别二维码的机制不同,也可能是因为浏览器内核原因,安卓的浏览器比较健壮。

  2. 为什么第一次进入页面的时候没有发生偏移?

 

此文转载。查看原文地址https://segmentfault.com/a/1190000005871183

posted @ 2017-05-22 09:42  Dios  阅读(732)  评论(0编辑  收藏  举报