淺析微信程序響應式像素實現原理

      網友投稿 1045 2022-05-30

      本次分享我們來談談微信小程序的響應式像素是如何實現的。

      官方文檔說明

      WXSS (WeiXin Style Sheets)是一套樣式語言,用于描述 WXML 的組件樣式。

      WXSS 用來決定 WXML 的組件應該怎么顯示。

      為了適應廣大的前端開發者,WXSS 具有 CSS 大部分特性。同時為了更適合開發微信小程序,WXSS 對 CSS 進行了擴充以及修改。

      尺寸單位

      rpx(responsive pixel): 可以根據屏幕寬度進行自適應。規定屏幕寬為750rpx。如在 iPhone6 上,屏幕寬度為375px,共有750個物理像素,則750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。

      那么在 iPhone6 的環境下,為什么寫了2rpx就會等同于1px呢?

      帶著疑問我們可以在解包之后的文件中找到答案。

      首先如果你讀過博主前面的文章,應該會知道小程序的本質是一個混合應用,是一堆js代碼,頁面結構及業務邏輯都是打包為js的,然后wxss樣式本身也是用服務端的編譯器去打包為js的,所以我們就可以從源碼上略知一二了。

      淺析微信小程序響應式像素實現原理

      如果你試著去尋找一下,會發現類似如下的代碼。

      這里我們節選一部分代碼來幫助理解所謂響應式像素的實現過程。

      var BASE_DEVICE_WIDTH = 750; var isIOS = navigator.userAgent.match('iPhone'); var deviceWidth = window.screen.width || 375; var deviceDPR = window.devicePixelRatio || 2; var checkDeviceWidth = window.__checkDeviceWidth__ || function () { var newDeviceWidth = window.screen.width || 375; var newDeviceDPR = window.devicePixelRatio || 2; var newDeviceHeight = window.screen.height || 375; if ( window.screen.orientation && /^landscape/.test(window.screen.orientation.type || '') ) newDeviceWidth = newDeviceHeight; if (newDeviceWidth !== deviceWidth || newDeviceDPR !== deviceDPR) { deviceWidth = newDeviceWidth; deviceDPR = newDeviceDPR; } }; checkDeviceWidth(); var eps = 1e-4; var transformRPX = window.__transformRpx__ || function (number, newDeviceWidth) { if (number === 0) return 0; number = (number / BASE_DEVICE_WIDTH) * (newDeviceWidth || deviceWidth); number = Math.floor(number + eps); if (number === 0) { if (deviceDPR === 1 || !isIOS) { return 1; } else { return 0.5; } } return number; };

      下面我們來一起看下吧~

      小程序頁面在注冊的過程中會定義一些變量:

      BASE_DEVICE_WIDTH,值為750,也就是官網所說的基準設備寬度(規定屏幕寬為750rpx)。

      deviceWidth,取值為屏幕寬度,默認值375。

      deviceDPR,設備上物理像素和邏輯像素的比例,所說的像素密度,默認為2。

      另外通過用戶代理(UA)來判斷設備是否為IOS,之后定義了一個全局變量checkDeviceWidth指向的一個掛載在window對象下全局函數__checkDeviceWidth__,如果window下面沒這個對象則直接返回一段檢查屏幕寬高的函數。如果是橫屏情況則會把屏幕寬度設為高度值,重新設置寬高。

      之后直接執行了這段函數checkDeviceWidth。

      再往下就是本次的關鍵部分了,定義了一個名為transformRPX的函數,看意思就知道了,作用是轉化rpx單位的,該函數支持傳入兩個參數:

      number

      newDeviceWidth

      這里大家應該明白了,傳入的第一個參數就是我們手寫的wxss樣式某標簽的具體寬高值,第二個則是設備寬度。

      函數內容也大致說下吧:

      如果傳的是0,比如0rpx,那轉換之后自然就是0了

      如果不是 0,則按公式((number / BASE_DEVICE_WIDTH) * (newDeviceWidth || deviceWidth))做了換算,就是按照傳入值與基準設備寬度得到的比率乘以當前設備寬度

      并且這里利用1e-4的eps值做了小量比較,即傳入的number值轉換之后加上eps并向下取整了。

      并且取整之后為0的情況,如果像素密度為1或者是非IOS設備則返回1,像素密度如果大的,或者IOS的設備就返回了0.5。

      大致的作用就解析到這里吧,頁面樣式最終轉換后還是以px為單位進行渲染的。

      所以會有同學又有疑問了,小程序運行環境中的webview下面到底認不識rpx呢?

      這里其實大家應該大概了解微信小程序的是如何根據屏幕寬度進行自適應顯示的思路了。

      當然這里只是簡要介紹了一下,真實情況要比這個復雜,我們從視圖層基礎庫的代碼中也可以窺探到一些有意思的東西,比如組件占位符的樣式,內聯樣式的轉換等等(有興趣的同學可以試著在基礎庫的 WAWebview.js 文件中去搜索一下 transformRpx)。

      參考資料

      wxss(https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.html)

      Math.floor()(https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/floor)

      使用 epsilon 比較浮點數(https://www.zhihu.com/question/37207811)

      iOS 小程序

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:Manticore search加一個中文分詞
      下一篇:特征匹配和單應性
      相關文章
      精品国产亚洲AV麻豆| 亚洲高清中文字幕免费| 亚洲AV无码乱码在线观看| 日韩亚洲产在线观看| 亚洲一级免费视频| 亚洲天堂一区二区三区四区| 亚洲毛片基地日韩毛片基地| 91亚洲国产成人精品下载| 亚洲福利一区二区精品秒拍| 亚洲欧洲久久精品| 亚洲av极品无码专区在线观看| 亚洲最大的黄色网| 亚洲黄色激情视频| 亚洲熟伦熟女专区hd高清| 亚洲精品美女久久久久久久| 亚洲精品无码不卡在线播放| 国产亚洲欧美日韩亚洲中文色| 精品无码专区亚洲| 亚洲国产精品无码久久青草 | 亚洲天天在线日亚洲洲精| 无码乱人伦一区二区亚洲一 | 亚洲一卡一卡二新区无人区| 亚洲综合精品第一页| 亚洲另类自拍丝袜第五页| 久久精品国产亚洲av天美18| 国产亚洲精品免费| 亚洲伊人成无码综合网| 亚洲国产精品嫩草影院在线观看| 亚洲国产高清视频| 亚洲国产午夜精品理论片| 久久亚洲最大成人网4438| 亚洲国产成人久久精品大牛影视| 成a人片亚洲日本久久| 亚洲男人天堂2020| 亚洲AV无码成人网站久久精品大| 激情内射亚洲一区二区三区| 亚洲婷婷第一狠人综合精品| 亚洲AV永久无码精品网站在线观看 | 97久久国产亚洲精品超碰热| 亚洲精品动漫免费二区| 亚洲精品国产综合久久一线|