進入移動Web世界

  • 2019 年 10 月 4 日
  • 筆記

# WebApp

一、 移動端web基礎

1. Pixel

  • px: CSS pixels 邏輯像素,瀏覽器使用的抽象單位;
  • dt,pt: 設備無關像素;
  • dpr: 設備像素縮放比;
  • 公式:1px = (dpr)2 * dp

默認縮放比例:

ldpi

mdpi

hdpi

xhdpi

ppi

120

160

240

320

默認縮放比例

0.75

1.0

1.5

2.0

2. Viewport

手機瀏覽器默認做了兩件事

  1. 頁面渲染在了一個默認的viewport;
  2. 縮放;

那麼問題來了,為什麼會有一個默認的viewport呢?我們知道,pc端頁面,在移動端查看的時候,由於像素不匹配,但是為了能夠給用戶展現一個比較完整的頁面,因此會虛擬出一個viewport出來,在此viewprot上渲染頁面。也就是說,最終目的,是為了排版正確。但是由於一般默認情況下,給出的viewport像素寬對頁面來說是不友好、不規範的,因此我們還需要解決一個規範問題。解決方案:在head中加一個meta標籤格式如下:<metaname="viewport"content="name=value, name=value">

3. meta標籤

<meta name="viewport" content="name=value, name=value">  // name = value 對應關係  width: device-width;  initial: xx;   // 設置初始縮放  minimum-scale: xx;  // 最小縮放  maxim-scale: xx;    // 最大縮放  user-scalable: no;  // 用戶不可縮放

二、 高效的移動web布局

1. flexbox彈性布局

  • flex布局混合排版
/* 混合使用flex佔比 */  .nav{      display: -webkit-flex;  }  .son1{      flex: 1;  }  .son2{      flex: 3;  }  .son3{      width: 100px;  }
  • flex水平垂直居中
.parent{      justify-content: center;      align-items: center;      display: -webkit-flex;  }

2. flex兼容性

  • iOS可以使用最新的flex布局;
  • Android4.4以下,只能兼容舊版flexbox布局;
  • Android4.4及以上,可以使用最新的flex布局;

表現如下:

新felx布局

舊flexbox布局

display: -webkit-flex;

display: -webkit-flex-box;

-weblit-flex: 1;

-weblit-flex-box: 1;

justify-content: center;

box-pack: center;

align-items: center;

box-align: cneter

3. 響應式設計

顧名思義,一套頁面,在所有端(pc、超大屏、ipad、手機等)完美運行。隨頁面寬高變化而改變頁面樣式,從而適配不同設備。

媒體查詢 @media

@media screen and (max-width: 1024px) {      body{          background: #eee;      }  }  @media screen and (max-width: 980px) {      body{          background: green;      }  }  @media screen and (max-width: 720px) {      body{          background: yellow;      }  }  @media screen and (max-width: 640px) {      body{          background: skyblue;      }  }  @media screen and (max-width: 320px) {      body{          background: pink;      }  }  @media screen and (min-width: 1025px) {      body{          background: darkseagreen;      }  }

媒體類型

  • screen:螢幕
  • print:印表機
  • handhead:手持設備
  • all:通用

常用參數說明

  • width: 視口寬
  • height: 視口高
  • device-width: 設備寬
  • device-height: 設備高
  • orientation: 檢查設備橫屏豎屏處向(landscape橫,portrait豎)

設計點

  1. 百分比布局:使切換css不同媒體樣式時更加平滑
  2. 彈性圖片:圖片根據盒子百分比,改變盒子寬高即可
  3. 重新布局,顯示和隱藏:
    • 同比例縮減元素尺寸
    • 調整頁面結構布局
    • 隱藏冗餘的元素

優劣比較

  • 優點:減少重複開發,一套程式碼多端兼容
  • 劣勢:在極端情況下影響頁面性能,含有較多的冗餘程式碼

4. 移動web特別樣式處理

a. 高清圖片處理

width: (wvalue / dpr)px height: (hvalue / dpr)px

b. 1像素邊框問題

問題: Retina螢幕下,1像素問題原因: 1px使用2dp渲染解決:

/* 錯誤案例 */  div{      border-top: 0.5px;  }    /* 正確案例 */  div:before{      border-top: 1px;      -webkit-transform: scaleY(0.5);      position: absolute;      top: -1px;      left: 0;      content: '';      height: 1px;  }

c. 相對單位

  • em: 根據父節點的font-size為相對單位
  • rem: 根據html的font-size為相對單位 (建議使用)

那麼,rem的基值設置為多少比較合適呢?回歸到開發中來,我們有一個公式:rem=screen.width/x例:320的螢幕,可以設置為font-size=32px,而375的螢幕,設置為37.5px。我們的目的是為了方便計算。

d. 文本溢出

/* 單行文本溢出*/  .line{      overflow: hidden;      white-space: nowrap;      text-overflow: ellipsis;  }    /* 多行文本溢出 */  .lines{      display: -webkit-box !important;      overflow: hidden;      text-overflow: ellipsis;      word-break: break-all;      -webkit-box-orient: vertical;      -webkit-line-clamp: 2;  // 行數  }

三、 終端交互優化

1. 300ms延遲問題

在移動端,由於有多重手勢操作替代了滑鼠操作,因此,為了判斷出是點擊、雙擊、觸摸移動或者別的手勢,iOS系統判斷中加了一個300毫秒的延遲:在第一次出發事件300毫秒內再次出發,例如點擊,就會被判斷為雙擊。那麼為了統一規範,後來在Android系統中也加入了此判定。這就是著名的移動端300ms延遲問題。那麼如何解決這個問題呢?tap事件處理。什麼是tap事件?簡而言之,就是通過touch,監聽touchstart和tarchend,如果兩者間隔較短,例如100ms甚至更短,且起始位置的偏移量極小,控制在幾個像素之內,那麼就判定為點擊事件。如此操作,可以繞過系統300ms的規範,從而在用戶體驗上做的更優。但我們只有,一般有利就有弊。我們解決掉300ms延遲問題,從而又產生了一個新的問題,就是穿透問題。例如在按鈕上有一個蒙層,我們點擊蒙層,關閉其蒙層。但是如果在蒙層下面同樣有點擊事件,那麼我們在點擊蒙層關閉後,也會觸發到下面的事件。那麼這種問題的一般解決方案便是關閉蒙層的時候,添加一個300ms的延時,經過300ms延時關閉後,點擊不再具有穿透性,巧妙的解決的該穿透問題。但是問題又來了,300ms延時其實對用戶體驗來講並不那麼友好。因此還是推薦第一種解決方案,不會出現拆東牆補西牆或者說捉襟見肘的問題。當然,如果使用框架庫的話,大部分強大的庫默認都解決了這個問題,不用開發者再為此操心。

2. touch相關

觸摸是移動設備交互的核心事件

a. 觸摸事件

事件

觸發情況

備註

touchstart

手指觸控螢幕幕觸發

已有手指放在螢幕上則不觸發

touchmove

手指在螢幕上滑動

連續觸發

touchend

手指離開螢幕時觸發

/

touchcancel

系統取消touch時觸發

不常用

b. 事件屬性

  • touches:跟蹤觸摸操作的touch對象數組
  • targetTouches:特定事件目標的touch對象數組
  • changeTouches:上次觸摸改變的touch對象數組

c. 每個touch對象包含屬性

  1. clientX:觸摸目標在視口中的橫坐標
  2. clientY:觸摸目標在視口中的縱坐標
  3. identifier:標識觸摸的唯一id
  4. pageX:觸摸目標在頁面中的橫坐標(含滾動)
  5. pageY:觸摸目標在頁面中的縱坐標(含滾動)
  6. screenX:觸摸目標在螢幕中的橫坐標
  7. screenY:觸摸目標在螢幕中的縱坐標
  8. target:觸摸的DOM節點的目標

d. 相關bug

在Android中,某些版本只會觸發一次touchstart和一次touchmove,不會觸發touchend。解決方案則是在事件中(touchmove)添加阻止默認事件:event.preventDefault()。但與此同時,要注意隨之產生的一個問題,就是組織默認事件後,頁面也會隨之禁止滾動,因此看情況使用。