日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

移动端适配(必须要知道的,亲测有效)

發布時間:2023/12/9 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 移动端适配(必须要知道的,亲测有效) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

關于移動端適配(必須要知道的,親測有效)

  • 一、各種單位概念理解
  • 二、移動,web開發
  • 三、移動端適配
    • 1、視口(viewport)概念
    • 2、視口(viewport)適配(代碼)
    • 3、rem單位適配
      • flexible方案
      • 豎屏、橫屏、ipad、PC最全的適配JS
    • 4、長屏短屏布局適配
    • 5、橫豎屏適配
      • css媒體查詢(CSS Media Queries)
      • window.orientation旋轉事件
    • window.innerHeight/window.innerWidth
      • 軟鍵盤彈出-影響橫豎屏判斷的坑
      • 強制橫豎屏時遇到的坑
      • 橫豎屏切換,全屏背景的坑
      • 在游戲接入中-H5隱藏某些模塊
    • 6、iphone適配
      • 概念
      • h5、小程序適配代碼
    • 7、常見適配問題
      • 1px問題
      • 圖片模糊問題

移動端適配,在開發中經常會遇到的問題:

一、各種單位概念理解

英寸:屏幕的物理大小,如電腦顯示器的17、22,手機顯示器的4.8、5.7等使用的單位都是英寸。一般說的屏幕的尺寸都是屏幕對角線的長度。1英寸 = 2.54 厘米

像素:像素即一個小方塊,它具有特定的位置和顏色。圖片、電子屏幕(手機、電腦)就是由無數個具有特定顏色和特定位置的小方塊拼接而成。像素可以作為圖片或電子屏幕的最小組成單位。

分辨率:屏幕分辨率(一個屏幕具體由多少個像素點組成。),圖像分辨率(指圖片含有的像素數。)。同一尺寸的屏幕、圖片,分辨率越高,越清晰。
PPI(Pixel Per Inch):每英寸包括的像素數。PPI越高,越清晰。
DPI(Dot Per Inch):即每英寸包括的點數。DPI和PPI是等價的。

DIP或DP 設備獨立像素:用來告訴不同分辨率的手機,它們在界面上顯示元素的大小是多少

dpr(device pixel ratio)設備像素比:物理像素和設備獨立像素的比值

//web let dpr = window.devicePixelRatio;//css 使用媒體查詢min-device-pixel-ratio區分 @media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2){ }//React Native PixelRatio.get()

web前端長度單位詳解(px、em、rem、%、vw/vh、vmin/vmax、vm、calc())

二、移動,web開發

移動端開發
1、在iOS、Android和React Native開發中樣式單位其實都使用的是設備獨立像素。

2、移動端開發中,UI給我們的原型圖一般是基于iphone6(750*1334)的像素給定的。

3、為了適配所有機型,我們在寫樣式時需要把物理像素轉換為設備獨立像素。

web開發
web端用到最多的單位是px,即CSS像素。當頁面縮放比例為100%時,一個CSS像素等于一個設備獨立像素
頁面的縮放系數 = 理想視口寬度 / 視覺視口寬度

三、移動端適配

1、視口(viewport)概念

視口共包括三種:布局視口、視覺視口和理想視口,它們在屏幕適配中起著非常重要的作用。

布局視口:在PC瀏覽器上,布局視口就等于當前瀏覽器的窗口大小(不包括borders 、margins、滾動條)。在移動端,布局視口被賦予一個默認值,大部分為980px

// 獲取布局視口大小 document.documentElement.clientWidth / clientHeight

視覺視口:用戶通過屏幕真實看到的區域。默認等于當前瀏覽器的窗口大小(包括滾動條寬度)

// 獲取視覺視口大小 window.innerWidth / innerHeight

理想視口:網站頁面在移動端展示的理想大小。在瀏覽器調試移動端時頁面上給定的像素大小就是理想視口大小,它的單位正是設備獨立像素。

screen.width / height // 獲取理想視口大小

獲取瀏覽器各種視口大小:

2、視口(viewport)適配(代碼)

<meta> 元素 元數據信息。 告訴瀏覽器如何解析頁面。可以借助<meta>元素的viewport來幫助我們設置視口、縮放等,從而讓移動端得到更好的展示效果 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />


為了在移動端讓頁面獲得更好的顯示效果,我們必須讓布局視口、視覺視口都盡可能等于理想視口。
設置width=device-width就相當于讓布局視口等于理想視口
設置initial-scale=1;就相當于讓視覺視口等于理想視口
這時,1個CSS像素就等于1個設備獨立像素,而且我們也是基于理想視口來進行布局的,所以呈現出來的頁面布局在各種設備上都能大致相似。

3、rem單位適配

flexible方案

核心代碼:

// set 1rem = viewWidth / 100function setRemUnit() {var rem = docEl.clientWidth / 7.5docEl.style.fontSize = rem + 'px'}setRemUnit()

豎屏、橫屏、ipad、PC最全的適配JS

<script type="text/javascript">// 設備區分 (安卓、火狐、平板、PC)var os = function() {var ua = navigator.userAgent,isAndroid = /(?:Android)/.test(ua),isFireFox = /(?:Firefox)/.test(ua),isTablet = /(?:iPad|PlayBook)/.test(ua) || (isAndroid && !/(?:Mobile)/.test(ua)) || (isFireFox && /(?:Tablet)/.test(ua)),isPC = !(/Android|webOS|iPhone|iPod|BlackBerry/i.test(ua));return {isTablet: isTablet,};}();(function (window, document) {function resize() {var docEl = document.documentElement;var clientWidth = docEl.clientWidth;var clientHeight = docEl.clientHeight;if (clientWidth < clientHeight) { // 手機豎屏docEl.style.fontSize = clientWidth / 7.5 + "px";} else { // 手機橫屏 docEl.style.fontSize = clientHeight / 7.5 + "px";}if(os.isTablet) { //ipad if(clientWidth >= 1366) {docEl.style.fontSize = clientWidth / 1366 * 100 + "px";} else {docEl.style.fontSize = clientWidth / 1024 * 100 + "px";}}if (os.isPC) { // pcif(clientWidth >= 1920) {docEl.style.fontSize = 1920 / 19.20 + "px";} else {docEl.style.fontSize = clientWidth / 19.20 + "px";}} }resize();// reset rem unit on page resizewindow.addEventListener("resize", function () {resize()});window.addEventListener('pageshow', function (e) {if (e.persisted) {resize()}});}(window, document)); </script>

4、長屏短屏布局適配

rem(font size of the root element)是指相對于根元素的字體大小的單位。雖然不同手機的寬高尺寸不一樣,但是設置了root font-size之后,每個手機的寬度都是等量的rem,可以理解為每個手機的寬度都是一樣的,區別在于高度不一樣。

有些單屏頁面內容很少,在短屏上超出一屏、剛好,在長屏上只占頁面頂上一小部分,布局會顯得不協調。

長屏短屏布局適配方案:
1、css媒體查詢,適當擴展間距讓內容撐滿更多高度
2、垂直定位盡量用%,不要用固定單位

5、橫豎屏適配

css媒體查詢(CSS Media Queries)

@media screen and (orientation: portrait) {/* 豎屏 */ } @media screen and (orientation: landscape) {/*橫屏 css*/ }

window.orientation旋轉事件

通過綁定orientationchange旋轉事件來判斷橫豎屏。
在 iOS 平臺以及大部分 Android 手機都有支持這個屬性,它返回一個與默認屏幕方向偏離的角度值:
0:代表此時是默認屏幕方向
90:代表順時針偏離默認屏幕方向90度
-90:代表逆時針偏離默認屏幕方向90度
180:代表偏離默認屏幕方向180度
如下圖所示:

在實際應用中,對于 iPhone 和大部分 Android 是沒有180度的手機豎屏翻轉的情況的,但是 iPad 是存在的。

function recordOrient() {if (window.orientation === 180 || window.orientation === 0) {//豎屏} else if (window.orientation === 90 || window.orientation === -90) {// 橫屏} }recordOrient(); window.addEventListener("onorientationchange" in window ? "orientationchange" : "resize", function () {recordOrient(); }, false);

彈框型js完美方案:

<meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" /> <title></title> <script type="text/javascript">(function (window, document) {function resize() {var docEl = document.documentElement;let clientWidth = docEl.clientWidth;let clientHeight = docEl.clientHeight;var k = 375;if (window.orientation === 180 || window.orientation === 0) {//豎屏} else if (window.orientation === 90 || window.orientation === -90) {//橫屏// k = 320;}if (clientWidth <= k) { //豎屏docEl.style.fontSize = clientWidth / 750 * 100 + "px";} else { //橫屏docEl.style.fontSize = k / 750 * 100 + "px";}}resize();// reset rem unit on page resizewindow.addEventListener("resize", function () {resize()});window.addEventListener('pageshow', function (e) {if (e.persisted) {resize()}});}(window, document));</script>

頁面型完美解決方案:

(function (win, doc) {if (!win.addEventListener) return;var html = document.documentElement;function setFont() {var html = document.documentElement;var k = 750;html.style.fontSize = html.clientWidth / k * 100 + "px";}setFont();setTimeout(function () {setFont();}, 300);doc.addEventListener('DOMContentLoaded', setFont, false);win.addEventListener('resize', setFont, false);win.addEventListener('load', setFont, false);})(window, document);

window.innerHeight/window.innerWidth

通過比較頁面的寬高,當頁面的高大于等于寬時則認為是豎屏,反之則為橫屏。

function detectOrient(){if(window.innerHeight >= window.innerWidth) {// 豎屏}else {// 橫屏 } } detectOrient(); window.addEventListener('resize',detectOrient);

軟鍵盤彈出-影響橫豎屏判斷的坑

在 Android 下,如果頁面中出現軟鍵盤彈出的情況(存在有 Input 的元素)時,頁面有時會因為軟鍵盤的彈出而導致頁面回縮,即頁面的寬度(豎屏時)或者高度(橫屏時)被改變。
所以通過 CSS多媒體查詢(CSS Media Queries) 、 window.matchMedia() 方法、window.innerWidth /window.innerHeight的頁面寬高比對方法來實現的橫豎屏判斷方法,都會因此受到影響,出現判斷失誤的情況(vivo x9、華為p9、Samsung SCH-i699 機型,在豎屏時由于軟鍵盤彈出導致頁面高度小于寬度,被錯誤地判定為橫屏)。
在這樣的情況下,這幾種方式也變得不可靠。

解決方案:類似的,在橫屏判斷中,給橫屏一個最小判斷寬度,低于那個寬度就還是判斷為豎屏

CSS 媒體查詢:給一個橫屏的最小寬度,即使高度很小,通過寬度還是可以區分橫豎屏 @media screen and (orientation: portrait) {/* 豎屏 */ } @media screen and (orientation: landscape) and (min-width: 560px) {/* 橫屏 */ }

vue 軟件盤彈出 css解決方案:

<template><div ref="app" id="app"><keep-alive><router-view v-if="$route.meta.keepAlive"></router-view></keep-alive><router-view v-if="!$route.meta.keepAlive"></router-view><shine-landscape></shine-landscape> // 組件</div> </template> <style lang="less" scoped> // 橫屏 && 軟鍵盤彈出橫屏 @media screen and (orientation: landscape) and (min-width: 560px) {/deep/ .shine-landscape{display: block;} }/style>

js 解決方案:

let sw = window.screen.width;let sh = window.screen.height;let cw = document.documentElement.clientWidth;if(cw == sw) {// 豎屏this.showShineLandscape = false}if(cw == sh) {// 橫屏this.showShineLandscape = true}

強制橫豎屏時遇到的坑

【問題】在 iOS 鎖屏情況下,強制豎屏不成功
【方案】做一個橫屏適配頁,內容可以是提示開啟鎖屏并自動旋轉手機屏幕
【注意】做適配時,如果發現在 iOS平臺,橫屏時頁面左右會有默認安全區域空白,我們需要定義頁面寬高等于手機視口寬高

@media screen and (orientation: landscape) and (min-width: 560px) {.page{/* 定義頁面寬高等于手機視口寬高 */width: 100vw;height: 100vh;background: #fff;position: relative;} }

【問題】做了強制橫豎屏,絕對不能使用window.orientation判斷來做橫豎屏適配,因為 ios平臺 旋轉屏幕會改變橫豎屏的值從而切換樣式,但視圖布局為始終保持強制的狀態,這就會導致旋轉屏幕時頁面樣式混亂。
【方案】:還是建議CSS多媒體查詢,比較簡單,解決缺陷的方式也簡單

【問題】橫豎屏旋轉canvas需要重新繪制
【問題】頁面中凡是 canvas繪制而成的局部視圖,橫豎屏旋轉,樣式不會跟著調整,
【方案】監聽旋轉屏幕事件,旋轉后刷新重繪canvas部分

<template> <div><template v-if="!isOrientationChange"><canvas id="my-canvas"/></template> </div> </template>data() {return {isOrientationChange: false} }, created() {const _this = this;window.addEventListener("onorientationchange" in window ? "orientationchange" : "resize", function () {_this.isOrientationChange = true;setTimeout(()=> {_this.isOrientationChange = false;}, 100)}, false); }

橫豎屏切換,全屏背景的坑

【問題】ios安全區域頁面留白,背景容器100%的漏洞
【解決方案】 背景容器設置100vw,vh

<div id="parent" class="parent"><div class="parent__banner"><img class="parent__img-portrait" src="./img/banner-portrait.png" alt="豎屏背景"><img class="parent__img-landscape" src="./img/banner-landscape.png" alt="橫屏背景"></div> </div> .parent{/* vw,vh適配ios安全區域頁面留白的漏洞 */width: 100vw;height: 100vh;background-color: #010c0f;position: relative;display: flex;align-items: center;justify-content: center; } .parent__banner{width: 100vw;height: 100vh;position: fixed;top: 0;left: 0; } .parent__img-portrait{display: block;width: 100%;height: 100%;object-fit:cover; }@media screen and (orientation: portrait) {/* 豎屏 */.parent__img-landscape{display: none;} } @media screen and (orientation: landscape) {/*橫屏 css*/.parent__img-landscape{display: none;} }

在游戲接入中-H5隱藏某些模塊

從游戲頁面操作跳轉到H5頁面。采用了window.location的跳轉方式,這里不能忘記手動攜帶該有的參數,否則從這里開始接下來所有頁面都失去了判斷的參數,項目中該去掉的模塊就會出現

/*** 獲得時間戳*/ function randomTimeStamp() {return parseInt(new Date().getTime() / 1000) + ''; } /*** 檢測flag* @param search*/ function checkFlag(search) {if (/[&|?](flag=[\d]+)/.test(search)) {search = search.replace(/[&|?](flag=[\d]+)/, (str) => {let splitStrs = str.split('=');return splitStrs[0] + '=' + randomTimeStamp();})} else {if (search) {search += '&flag=' + randomTimeStamp();} else {search += '?flag=' + randomTimeStamp();}} return search; } /*** 拼接地址* @param path: 路由* @param flag: 是否需要刷新*/ function locationUrl(path, flag = true) {let url = '';if (flag) {let search = checkFlag(location.search);url = location.protocol + '//' + location.host + location.pathname + search + '#/' + path;} else {url = location.protocol + '//' + location.host + location.pathname + location.search + '#/' + path;}window.location = url; }this.locationUrl('Index');

6、iphone適配

概念

安全區域適配
iphone x\xr\xs\11 pro 取消了物理按鍵,改成底部小黑條,這一改動導致網頁出現了比較尷尬的屏幕適配問題。
對于網頁而言,頂部(劉海部位)的適配問題瀏覽器已經做了處理,所以我們只需要關注底部與小黑條的適配問題即可(即常見的吸底導航、返回頂部等各種相對底部 fixed 定位的元素)。如下圖:

安全區域:一個可視窗口范圍,處于安全區域的內容不受圓角(corners)、齊劉海(sensor housing)、小黑條(Home Indicator)影響。

viewport-fit:iOS11 新增特性,蘋果公司為了適配 iPhoneX 對現有 viewport meta 標簽的一個擴展,用于設置網頁在可視窗口的布局方式,可設置 三個值:
auto \ contain: 可視窗口完全包含網頁內容(左圖)。頁面內容顯示在safe area內
cover:網頁內容完全覆蓋可視窗口(右圖)。頁面內容充滿屏幕。

env() 和 constant():iOS11 新增特性,Webkit 的一個 CSS 函數,用于設定安全區域與邊界的距離,有四個預定義的變量:

safe-area-inset-left:安全區域距離左邊邊界距離
safe-area-inset-right:安全區域距離右邊邊界距離
safe-area-inset-top:安全區域距離頂部邊界距離
safe-area-inset-bottom:安全區域距離底部邊界距離

【注意】:
1)網頁默認不添加擴展的表現是 viewport-fit=contain,需要適配 iPhoneX 必須設置 viewport-fit=cover,不然 constant 函數是不起作用的,這是適配的必要條件
2)env() 是官方文檔中提到將來要替換 constant (),目前還不可用。
為此目前我們可以看作 constant:針對iOS < 11.2以下系統,env:針對于iOS >= 11.2的系統
使用的時候 env() 必須寫在 constant () 后面

h5、小程序適配代碼

第一步:設置網頁在可視窗口的布局方式 (viewport-fit=cover")

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />

第二步:頁面主體內容限定在安全區域內

body {padding-top: constant(safe-area-inset-top); padding-top: env(safe-area-inset-top); padding-bottom: constant(safe-area-inset-bottom);padding-bottom: env(safe-area-inset-bottom); }

第三步:相對底部 fixed 定位的元素適配
1、fixed吸底 元素(bottom = 0)

<div class="footer ipx-padding-safe-area"></div> // 或者 <div class="footer ipx-height-safe-area"></div> // 或者 <div class="footer ipx-margin-safe-area"></div> <div class="ipx-footer-safe-area"></div> /* 通過加內邊距 padding 擴展高度 */ .ipx-padding-safe-area{padding-bottom: constant(safe-area-inset-bottom);padding-bottom: env(safe-area-inset-bottom); } /* 通過計算函數 calc 覆蓋原來高度 */ .ipx-height-safe-area{height: calc(1rem + constant(safe-area-inset-bottom));height: calc(1rem + env(safe-area-inset-bottom)); } /* 通過加外邊距 margin 增加底部距離 */ .ipx-margin-safe-area{margin-bottom: constant(safe-area-inset-bottom);margin-bottom: env(safe-area-inset-bottom); } /* 以上方式需要吸底條必須是有背景色的,因為擴展的部分背景是跟隨外容器的,否則出現鏤空情況。 還有一種方案就是,可以通過新增一個新的元素(空的顏色塊,主要用于小黑條高度的占位),然后吸底元素可以不改變高度只需要調整位置 */ .ipx-footer-safe-area{position: fixed;bottom: 0;width: 100%;height: constant(safe-area-inset-bottom);height: env(safe-area-inset-bottom);background-color: #fff; }

2、fixed 非完全吸底元素(bottom ≠ 0),比如 “返回頂部”、“側邊廣告” 等

<div class="back-top ipx-margin-safe-area">返回頂部</div>

第四步:使用 @supports 隔離兼容樣式(可有可無)

@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {/* 通過加內邊距 padding 擴展高度 */.ipx-padding-safe-area{padding-bottom: constant(safe-area-inset-bottom);padding-bottom: env(safe-area-inset-bottom);}... }

7、常見適配問題

1px問題

【問題】:在設備像素比大于1的屏幕上,我們寫的1px實際上是被多個物理像素渲染,這就會出現1px在有些屏幕上看起來很粗的現象
【方案】:偽類 + transform 基于media查詢判斷不同的設備像素比對線條進行縮放

/* 邊框線條 top\bottom */ .border-top, .border-bottom{position: relative; } .border-top:before{content: '';position: absolute;top: 0;height: 1px;width: 100%;background-color: #000;transform-origin: 50% 0%; } .border-bottom:before{content: '';position: absolute;bottom: 0;height: 1px;width: 100%;background-color: #000;transform-origin: 50% 0%; } @media only screen and (-webkit-min-device-pixel-ratio:2){.border-top:before, .border-bottom:before{transform: scaleY(0.5);} } @media only screen and (-webkit-min-device-pixel-ratio:3){.border_1px:before, .border-bottom:before{transform: scaleY(0.33);} }

圖片模糊問題

【問題】:我們平時使用的圖片大多數都屬于位圖(png、jpg…)。在dpr > 1的屏幕上,位圖的一個像素可能由多個物理像素來渲染,然而這些物理像素點并不能被準確的分配上對應位圖像素的顏色,只能取近似值,所以相同的圖片在dpr > 1的屏幕上就會模糊
【方案】:在dpr=2的屏幕上展示兩倍圖(@2x),在dpr=3的屏幕上展示三倍圖(@3x)

1、媒體查詢縮放(只適用于背景圖)

@media only screen and (-webkit-min-device-pixel-ratio:2){.bg1{transform: scaleY(0.5);} } @media only screen and (-webkit-min-device-pixel-ratio:3){.bg1{transform: scaleY(0.33);} }

2、image-set

.avatar {background-image: -webkit-image-set( "conardLi_1x.png" 1x, "conardLi_2x.png" 2x ); }

3、使用img標簽的srcset屬性

<img src="conardLi_1x.png"srcset=" conardLi_2x.png 2x, conardLi_3x.png 3x">

4、使用svg可縮放矢量圖

總結

以上是生活随笔為你收集整理的移动端适配(必须要知道的,亲测有效)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。