1. 程式人生 > >移動端常見問題處理

移動端常見問題處理

前面的話

  本文將詳細介紹移動web開發中的常見問題

Input

【游標顏色】

  預設情況下,游標顏色與字型顏色color相同,但也可以通過caret-color屬性來單獨設定

caret-color: auto;
caret-color: transparent;
caret-color: currentColor;
caret-color: red;
caret-color: #5729e9;
caret-color: rgb(0, 200, 0);
caret-color: hsla(228, 4%, 24%, 0.8);

  但是,IOS的游標不支援caret-color,與字型顏色無關,預設為紫藍色。所以,儘量不要設定藍色或紫色背景,否則游標看不清楚

【游標高度】

  input域的游標高度與行高line-height相同,所以不要設定太高的行高,可以通過設定上下padding來撐開高度

【放大】

  IOS下,input獲取焦點時會放大,meta設定user-scalable=no,可取消放大效果

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

【自動大寫】

  一般地,IOS下預設開啟鍵盤的首字母自動大寫功能,這樣輸入英文的時候,首字母便會自動大寫

大寫

  但是,有些時候並不希望一直是首字母大寫的。比如使用者名稱這個欄位,如果欄位本身就是區分大小寫的,首字母自動大寫往往會給使用者帶來麻煩。可以通過在表單元素上可以通過設定autocapitalize="off"來關閉

<input type="text" autocapitalize="off">

【圓角】

  IOS下,input域只顯示底邊框時,會出現兩個底部底邊圓角效果,設定border-radius:0即可

border-radius:0

【自動儲存】

  input域預設會開啟自動儲存功能,可以使用autocomplete="off"屬性將其關閉

<input autocomplete="off" />

  要特別注意的是,如果使用react框架,需要將autocomplete替換為autoComplete這種小駝峰形式

【輪廓outline】

  android瀏覽器下,input域處於焦點狀態時,預設會有一圈淡黃色的輪廓outline效果

  通過設定outline:none可將其去除

outline: none

【虛擬鍵盤】

  IOS彈出虛擬鍵盤不影響可視區域大小,而android手機彈出虛擬鍵盤時會影響。所以,最好將包含input域的頁面高度設為固定

  在頁面初始化時,獲取頁面高度

// app.js
  componentDidMount() {
    const { setWrapSize } = this.props
    const { clientHeight, clientWidth } = document.documentElement
    setWrapSize({ clientHeight, clientWidth })
    window.addEventListener('orientationchange', this.setSize)
  }

  然後通過行間樣式,將此高度設定到包含input域的頁面上

// BaseFullScreen
<Wrap className={className} style={{ height: `${wrapHeight}px` }} {...rest}>{children}</Wrap>

樣式

【點選背景】

  在移動端,點選可點選元素時,android下會出現淡藍色背景,IOS下會出現灰色背景

bg

  可以通過-webkt-tap-hightlight-color屬性的設定,取消點選時出現的背景效果

* {
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

【appearance】

  使用appearance:none主要用來去除表單類元素的中瀏覽器內建樣式,如去除data型別input域的叉叉,去除number型別input域的上下箭頭等

-webkit-appearance: none;

【禁止選中】

  有時不希望使用者在網站上選擇文字,或許是出於版權的原因,如電子書網站。通常使用js來實現

  另一個方案就是,將-webkit-user-select設為none

-webkit-user-select:none;

【禁止文字縮放】

  部分手機上,切換橫豎屏時,會縮放字型。使用如下設定,可以禁止文字縮放

* {
  -webkit-text-size-adjust:100%;
}

【文字渲染】

  使用text-rendering:optimizeLegibility屬性,可以讓瀏覽器在繪製文字時將著重考慮易讀性,而不是渲染速度和幾何精度.它會使字間距和連字有效

text-rendering: optimizeLegibility;

  該屬性在移動裝置上會造成比較明顯的效能問題

【文字平滑顯示】

  -webkit-font-smoothing屬性可以用來控制字型的畫素顯示是否平滑

none 關閉抗鋸齒,字型邊緣犀利。
antialiased 字型畫素級平滑,在深色背景上會讓文字看起來更細了
subpixel-antialiased 字型亞畫素級平滑,主要為了在非視網膜裝置下更好的顯示
body { -webkit-font-smoothing: antialiased; }

【輪廓outline】

  input、textarea等表單類標籤,在獲取焦點的情況下,在andriod系統下,會出現淡黃色輪廓outline,使用outline:none將其去除

outline: none

【placeholder】

  placeholder預設是淺灰色,如果input域是淺灰色背景,則這時placeholder的文字與背景顏色相近,無法清晰顯示,就需要設定placeholder的顏色

  可以通過偽元素來進行設定

::placeholder {
    color: #fff;
  }

【清除按鈕圓角】

input,button{
  -webkit-appearance:none;
  border-radius:0;
}

【滾動回彈】

  -webkit-overflow-scrolling 屬性控制元素在移動裝置上是否使用滾動回彈效果

auto 使用普通滾動, 當手指從觸控式螢幕上移開,滾動會立即停止
touch 使用具有回彈效果的滾動, 當手指從觸控式螢幕上移開,內容會繼續保持一段時間的滾動效果。繼續滾動的速度和持續的時間和滾動手勢的強烈程度成正比。同時也會建立一個新的堆疊上下文
body {
  -webkit-overflow-scrolling: touch;
}

  一定要設定該屬性,否則在IOS下會出現區域性滾動不流暢的bug

【1倍行高】

  設定line-height:1,即行高為1時,有的頁面會出現文字顯示不全的情況,所以行高設定一定要大於1

1畫素邊框

  由於retina屏的原因,1px 的 border 會顯示成兩個物理畫素,所以看起來會感覺很粗,這是一個移動端開發常見的問題

  解決方案有很多,但都有自己的優缺點

  1、0.5px 邊框

  從iOS 8開始,iOS 瀏覽器支援 0.5px 的 border,但是在 Android 上是不支援的,0.5px 會被認為是 0px,所以這種方法,相容性很差

  2、背景漸變

  CSS3 有了漸變背景,可以通過漸變背景實現 1px 的 border,實現原理是設定 1px 的漸變背景,50% 有顏色,50% 是透明的

@mixin commonStyle() {
  background-size: 100% 1px,1px 100% ,100% 1px, 1px 100%;
  background-repeat: no-repeat;
  background-position: top, right top,  bottom, left top;
}
@mixin border($border-color) {
  @include commonStyle();
  background-image:linear-gradient(180deg, $border-color, $border-color 50%, transparent 50%),
  linear-gradient(270deg, $border-color, $border-color 50%, transparent 50%),
  linear-gradient(0deg, $border-color, $border-color 50%, transparent 50%),
  linear-gradient(90deg, $border-color, $border-color 50%, transparent 50%);
}

  3、偽類 + transform

  這類方法的實現原理是用偽元素高度設定為1px,然後用 transform縮小到原來的一半

div {
  position: relative;
  &::after {
    position: absolute;
    left: 0;
    right: 0;
    height: 1px;
    transform: scaleY(.5);
    content: '';
  }
`

佈局

【vh】

  頁面使用vh來控制元素高度的時候,在安卓端瀏覽器虛擬鍵盤彈出時,導致視口高度改變,以至於vh的取值改變

// 正常模式下
100vh = document.documentElement.clientHeight;

// 安卓端彈出虛擬鍵盤情況下
100vh = document.documentElement.clientHeight - 虛擬鍵盤的高度;

  這種情況導致了在虛擬鍵盤彈出時,頁面中使用vh定高的元素的大小被壓縮,造成佈局錯位以及文字溢位

  所以,最好將包含input域的頁面高度設為固定

【100%與100vh】

  100vh指的是視口,即螢幕高度的100%,不僅包括瀏覽器可視高度,還包括瀏覽器位址列高度。而100%高度,是頁面高度的100%

  所以,在全屏情況下,100vh等於100%高度,否則,100vh大於100%高度

【高度無效】

  在IOS下,設定height:100%,如果父級的flex值為1,而沒有設定具體高度,則100%高度設定無效

  處理方法是,在父級通過計算來設定具體高度height,如height: calc(100% - 100px)

事件

【滑鼠事件】

  由於移動裝置沒有滑鼠,所以與電腦端有一些不同之處

  1、不支援dblclick雙擊事件。在移動裝置中雙擊瀏覽器視窗會放大畫面

  2、單擊元素會觸發mousemove事件

  3、兩個手指放在螢幕上且頁面隨手指移動而滾動時會觸發mousewheel和scroll事件

【touch事件】

  新版的chrome下,不支援直接給document和body設定touch事件,所以下列程式碼無效

document.addEventListener('touchstart', function(e) {
  e.preventDefault();
})

圖片

【SVG】

  SVG圖片由於其向量的性質,縮放不失真,則程式碼量較少,大量地應用在小圖示上。但在使用的過程中,有一些要注意的地方

  1、在偽類中新增SVG,在IOS下svg不顯示

  2、在頁面中新增SVG,在android的微信中下會出現設定透明度opacity的元素有的不顯示的情況,所以儘量不設定透明度

  3、在mask屬性中設定SVG,可以通過background-color給SVG變換顏色

【base64】

  要特別注意的是,圖片變化base64格式之後,再新增查詢字串,會報錯

【快取】

  移動端更改同名圖片無法清除快取。所以,還是要在圖片命名上做文章

meta

【shrink-to-fit=no】

  IOS9+系統下,使用Viewport元標記"width=device-width"會導致頁面縮小以適應溢位視口邊界的內容。可以通過新增"shrink-to-fit=no"到meta標籤來覆蓋此行為,增加的值將阻止頁面縮放以適應視口

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

【頁面縮放】

  在meta標籤中設定了禁止縮放user-scalable=no,可以實現在IOS下input域焦點狀態時放大被禁止的效果。但是,仍然無法阻止頁面整體的縮放

 【識別規則】

  1、打電話

<a href="tel:0755-10086">打電話給:0755-10086</a>

  2、發簡訊,winphone系統無效

<a href="sms:10086">發簡訊給: 10086</a>

   3、跳轉到地圖

<a href="iosamap://viewMap?sourceApplication=yukapril&poiname=國巨集賓館&lat=39.905592&lon=116.33604&dev=0">高德地圖</a>
<a href="androidamap://viewMap?sourceApplication=yukapril&poiname=國巨集賓館&lat=39.905592&lon=116.33604&dev=0">高德</a>

  4、寫郵件

<a href="mailto:[email protected]">[email protected]</a>

  5、禁止識別

<meta name="format-detection" content="telephone=no,email=no,address=no"/>

【爬蟲】

   robots(網頁搜尋引擎索引方式):對應一組使用逗號(,)分割的值,通常取值:

none:搜尋引擎將忽略此網頁,等同於noindex,nofollow;
noindex:搜尋引擎不索引此網頁;nofollow:搜尋引擎不繼續通過此網頁的連結索引搜尋其它的網頁;
all:搜尋引擎將索引此網頁與繼續通過此網頁的連結索引,等同於index,follow;
index:搜尋引擎索引此網頁;follow:搜尋引擎繼續通過此網頁的連結索引搜尋其它的網頁;

  使用下列程式碼,則網頁會被搜尋引擎忽略

<meta name="robots" content="none"/>

【新增到主螢幕】

  在IOS下,在head元素底部,使用下列程式碼可以實現新增到主螢幕的功能

  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <meta name="apple-mobile-web-app-title" content="Weather PWA">
  <link rel="apple-touch-icon" href="images/icons/icon-152x152.png">

【QQ瀏覽器】

// 全屏模式
<meta name="x5-fullscreen" content="true">
// 強制豎屏
<meta name="x5-orientation" content="portrait">
// 強制橫屏
<meta name="x5-orientation" content="landscape">
// 應用模式
<meta name="x5-page-mode" content="app">

【UC瀏覽器】

// 全屏模式
<meta name="full-screen" content="yes">
// 強制豎屏
<meta name="screen-orientation" content="portrait">
// 強制橫屏
<meta name="screen-orientation" content="landscape">
// 應用模式
<meta name="browsermode" content="application">