1. 程式人生 > >關於viewport引起的微信二維碼識別區域偏移的問題討論與解決

關於viewport引起的微信二維碼識別區域偏移的問題討論與解決

ges 瀏覽器內核 不同 清晰 css 工作量 分辨 轉換成 如果

一、問題概述

在開發一個含有二維碼的微信頁面時,我遇到了這樣一個問題:使用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和移動設備屏幕密度像素的不同在輸出視覺稿的時候要標明空間的倍數大小,[email protected]@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

關於viewport引起的微信二維碼識別區域偏移的問題討論與解決