[移動端]移動端上遇到的各種坑與相對解決方式


mobileHack

這里收集了很多移動端上遇到的各種坑與相對解決方式

1.問題:手機端 click 事件會有大約 300ms 的延遲

原因:手機端事件 touchstart –> touchmove –> touchend or touchcancel –> click。由於在touch事件觸發之后,瀏覽器要推斷用戶是否會做出雙擊屏幕的操作,所以會等待300ms來推斷,再做出是否觸發click事件的處理。所以就會有300ms的延遲

解決方法:使用touch事件來取代click事件。如 zepto.js 的tap事件和fastClick,還有我自己也寫了個移動端手勢操作庫mTouch。都有對應的事件能夠取代click事件解決問題

2.問題:在部分機型下(如小米4、小米2s、中興) body 設置的 font-size 是用 rem 單位的話,若其它元素沒有設置font-size,該font-size值繼承於body,則會非常高概率出現字體異常變大的情況

原因:預計是跟app的webview默認設置有關。body的font-size使用rem單位,就是相對於當前根節點的font-size來確定的,可能在某些webview的設置下。body用的是webview設置的默認字體大小。由於在我給html設置了一個px單位的默認font-size時,還是會出現字體異常變大的情況,具體webview的一些細節就沒有再研究了

解決方法:body設置一個px單位的默認font-size值,不用rem,或者給字體會異常變大的元素設定一個px單位的font-size值

3.問題:使用zepto的 tap 事件時會出現“點透”bug,比方:一個元素A綁定了tap事件,緊跟其后的元素B綁定了click事件,A觸發tap事件時將自己remove掉。B就會自己主動“掉”到A的位置。接下來就是不正常的情況,由於這個時候B的click事件也觸發了

原因:由於tap事件是通過 touchstart 、touchmove 、 touchend 這三個事件來模擬實現的,在手機端事件機制中,觸發touch事件后會緊接着觸發touch事件坐標元素的click事件。由於B元素在300ms內剛好“掉”回來A的位置。所以就觸發了B的click事件。還有zepto的tap事件都是代理到body的,所以想通過e.preventDefault()阻止默認行為也是不可行的

解決方法:(1)A元素換成click事件。(2)使用我寫的庫 mTouch 來給A綁定tap事件。然后在事件回調中通過e.preventDefault()來阻止默認行為,或者換用其它的支持tap事件的庫

問題、4.動畫

動畫有非常多種,比方側邊欄菜單的滑入滑出、元素的響應動畫、頁面切換之間的過場等等,在H5之下的眾多實現方法都沒有辦法達到純原生的性能。一般這些的話有幾種不同的選擇:css3動畫。javascript動畫,原生動畫。css3動畫非常的消耗性能,假設某一個元素用到css3動畫可能還看不出來。但大面積或過場使用css3動畫會讓app低端手機體驗非常差。最好的選擇通常是通過框架調用底層的動畫,但無論怎么樣等於在原來的代碼上包上了一層,性能還是不可避免的受到影響。比方在一個新頁面的載入上,假設調用底層動畫要考慮的問題有兩個。一個是本身資源頁面的渲染問題,另一個是遠程數據的獲取。即便是這些動畫能夠非常快的響應,但大量的css頁面會導致渲染卡頓,滑入時可能會有白屏/機器卡頓的現象。為了解決這些性能問題又必須要用到預載入或模擬動畫。即便是這樣,滑入滑出的動畫在低端的安卓機器上還是有非常多問題,假設獲取服務端數據處理的方式不合適,卡頓白屏的現象會更嚴重。具體看下面的數據獲取方式。

問題、5.獲取服務端數據

首先要接受的是。這里的數據獲取都是在資源頁面上異步完畢的,由於僅僅有這樣才干讓這些資源頁面完畢預載入或者渲染。

可是異步拿到的數據在填入頁面中時可能會涉及DOM操作。眾所周知,DOM操作非常消耗性能,假設頁面小還好,頁面稍大數據略微復雜一點。頻繁的DOM操作會導致明顯的閃白。而且最重要的一點是。假設頁面載入進來之后數據更新的速度太慢。也會讓頁面模板等待非常長時間,對用戶體驗又不友好,總不能每次打開都像瀏覽器一樣等待刷新是吧。這個問題假設沒有得到解決。H5APP是非常難承擔大規模數據的頁面,在它們之中頻繁切換更是難上加難,那么肯定有人也會想到用MVVM的方式,事實上我也寫過一些基於MVVM的H5APP。相對來說它們獲取數據和更新數據的方式更敏捷更科學。但寫的過程中又要注意非常多H5獨有的問題,這些問題在下面的頁面切換里來講。

一些實用技能點

通過設置css屬性 -webkit-tap-highlight-color: rgba(0, 0, 0, 0);取消掉手機端webkit瀏覽器 點擊button或超鏈接之類的 默認灰色背景色
設置css屬性 -webkit-user-select:none; 控制用戶不可選擇文字
區域性 overflow: scroll | auto 滾動時使用原生效果:-webkit-overflow-scrolling: touch (ios8+。Android4.0+)

工具類站點

HTML5 與 CSS3 技術應用評估

各種奇異的hack

差點兒全部設備的屏幕尺寸與像素密度表

移動設備參數表

ios端移動設備參數速查

瀏覽器兼容表

移動設備查詢器

移動設備適配庫

移動設備適配庫2

viewport與設備尺寸在線檢測器

html5 移動端兼容性速查

在線轉換字體

css3 選擇器測試

兼容性速查表

瀏覽器的一些獨特參數

各種各樣的媒體查詢收集

css3 動畫在線制作器

css3 漸變在線制作器

移動端手勢表

webkit獨有的樣式分析

HTML5 Cross Browser Polyfills

HTML5 POLYFILLS

iphone6的那些事

iPhone 6 屏幕揭秘

響應式測試工具

Firefox 瀏覽器內置了 自己定義設計視圖 的功能。能夠通過 Firefox->Web 開發人員->自己定義設計視圖(或者摁下 Shift + Ctrl + m )。相比網絡工具,運行更加流暢,無需聯網。

推斷 iPad 和 iPhone 的版本號和狀態的 CSS 媒體查詢代碼

Viewport Resizer

http://beta.screenqueri.es/

http://responsivepx.com

http://www.responsinator.com/

http://resizemybrowser.com/

https://quirktools.com/screenfly/

媒體查詢經常使用樣式表:

    <link rel="stylesheet" media="all and (orientation:portrait)" href="portrait.css">    // 豎放載入
    <link rel="stylesheet" media="all and (orientation:landscape)"href="landscape.css">   // 橫放載入
豎屏時使用的樣式
    <style media="all and (orientation:portrait)" type="text/css"> #landscape { display: none; } </style>
//橫屏時使用的樣式
    <style media="all and (orientation:landscape)" type="text/css"> #portrait { display: none; } </style>

Web app 開發的最佳實踐與中文總結

It’s not a web app. It’s an app you install from the web.

當前 WEB APP 開發的最佳實踐

怎樣自適應網頁屏幕
以及配套的解決方式

來自maxzhang的一些移動端經驗總結干貨

移動Web單頁應用開發實踐——頁面結構化

移動Web產品前端開發口訣——“快”

移動Web開發。4行代碼檢測瀏覽器是否支持position:fixed

使用border-image實現相似iOS7的1px底邊

移動端web頁面使用position:fixed問題總結

移動Web開發實踐——解決position:fixed自適應BUG

移動手機瀏覽器m3u8格式視頻流播放支持程度測試

本資料非常多引用了指尖上的js系列

指尖下的js ——多觸式web前端開發之中的一個:對於Touch的處理

指尖下的js ——多觸式web前端開發之二:處理簡單手勢

指尖下的js —— 多觸式web前端開發之三:處理復雜手勢

基礎知識

meta標簽

meta標簽大全 http://segmentfault.com/blog/ciaocc/1190000002407912

meta標簽。這些meta標簽在開發webapp時起到非常關鍵的數據

    <meta content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0" name="viewport" />
    <meta content="yes" name="apple-mobile-web-app-capable" />
    <meta content="black" name="apple-mobile-web-app-status-bar-style" />
    <meta content="telephone=no" name="format-detection" />

第一個meta標簽表示:強制讓文檔的寬度與設備的寬度保持1:1。而且文檔最大的寬度比例是1.0,且不同意用戶點擊屏幕放大瀏覽;
尤其要注意的是content里多個屬性的設置一定要用分號+空格來隔開,假設不規范將不會起作用。

注意依據 public_00 提供的資料補充,content 使用分號作為分隔,在老的瀏覽器是支持的。但不是規范寫法。

規范的寫法應該是使用逗號分隔,參考 Safari HTML Reference - Supported Meta TagsAndroid - Supporting Different Screens in Web Apps

當中:

  • width - viewport的寬度
  • height - viewport的高度
  • initial-scale - 初始的縮放比例
  • minimum-scale - 同意用戶縮放到的最小比例
  • maximum-scale - 同意用戶縮放到的最大比例
  • user-scalable - 用戶能否夠手動縮放

第二個meta標簽是iphone設備中的safari私有meta標簽,它表示:同意全屏模式瀏覽;
第三個meta標簽也是iphone的私有標簽。它指定的iphone中safari頂端的狀態條的樣式。
第四個meta標簽表示:告訴設備忽略將頁面中的數字識別為電話號碼

在設置了initial-scale=1 之后,我們最終能夠以1:1 的比例進行頁面設計了。
關於viewport。另一個非常重要的概念是:iphone 的safari 瀏覽器全然沒有滾動欄。而且不是簡單的“隱藏滾動欄”,
是根本沒有這個功能。iphone 的safari 瀏覽器實際上從一開始就完整顯示了這個網頁,然后用viewport 查看當中的一部分。
當你用手指拖動時,事實上拖的不是頁面,而是viewport。瀏覽器行為的改變不止是滾動欄,交互事件也跟普通桌面不一樣。
(請參考:指尖的下JS 系列文章)

更具體的 viewport 相關的知識也能夠參考

此像素非彼像素

移動開發事件

手機瀏覽器經常使用手勢動作監聽封裝

手勢事件

  • touchstart //當手指接觸屏幕時觸發
  • touchmove //當已經接觸屏幕的手指開始移動后觸發
  • touchend //當手指離開屏幕時觸發
  • touchcancel

觸摸事件

  • gesturestart //當兩個手指接觸屏幕時觸發
  • gesturechange //當兩個手指接觸屏幕后開始移動時觸發
  • gestureend

屏幕旋轉事件

  • onorientationchange

檢測觸摸屏幕的手指何時改變方向

  • orientationchange

touch事件支持的相關屬性

  • touches
  • targetTouches
  • changedTouches
  • clientX    // X coordinate of touch relative to the viewport (excludes scroll offset)
  • clientY    // Y coordinate of touch relative to the viewport (excludes scroll offset)
  • screenX    // Relative to the screen
  • screenY    // Relative to the screen
  • pageX     // Relative to the full page (includes scrolling)
  • pageY     // Relative to the full page (includes scrolling)
  • target     // Node the touch event originated from
  • identifier   // An identifying number, unique to each touch event
  • 屏幕旋轉事件:onorientationchange

推斷屏幕是否旋轉

    function orientationChange() {
        switch(window.orientation) {
          case 0:
                alert("肖像模式 0,screen-width: " + screen.width + "; screen-height:" + screen.height);
                break;
          case -90:
                alert("左旋 -90,screen-width: " + screen.width + "; screen-height:" + screen.height);
                break;
          case 90:
                alert("右旋 90,screen-width: " + screen.width + "; screen-height:" + screen.height);
                break;
          case 180:
              alert("風景模式 180,screen-width: " + screen.width + "; screen-height:" + screen.height);
              break;
        };};

    addEventListener('load', function(){
        orientationChange();
        window.onorientationchange = orientationChange;
    });

JS 單擊延遲

click 事件由於要等待單擊確認,會有 300ms 的延遲,體驗並非非常好。

開發人員大多數會使用封裝的 tap 事件來取代click 事件,所謂的 tap 事件由 touchstart 事件 + touchmove 推斷 + touchend 事件封裝組成。

Creating Fast Buttons for Mobile Web Applications

Eliminate 300ms delay on click events in mobile Safari

WebKit CSS:

攜程 UED 整理的 Webkit CSS 文檔 ,全面、方便查詢,下面為經常使用屬性。

①“盒模型”的具體描寫敘述性質的包圍盒塊內容,包含邊界,填充等等。
css
-webkit-border-bottom-left-radius: radius;
-webkit-border-top-left-radius: horizontal_radius vertical_radius;
-webkit-border-radius: radius; //容器圓角
-webkit-box-sizing: sizing_model; 邊框常量值:border-box/content-box
-webkit-box-shadow: hoff voff blur color; /*容器陰影(參數分別為:水平X 方向偏移量。垂直Y方向偏移量。高斯模糊半徑值;陰影顏色值)*/
-webkit-margin-bottom-collapse: collapse_behavior; /*常量值:collapse/discard/separate*/
-webkit-margin-start: width;
-webkit-padding-start: width;
-webkit-border-image: url(borderimg.gif) 25 25 25 25 round/stretch round/stretch;
-webkit-appearance: push-button; /*內置的CSS 表現,臨時僅僅支持push-button*/

②“視覺格式化模型”描寫敘述性質,確定了位置和大小的塊元素。

direction: rtl
unicode-bidi: bidi-override; 常量:bidi-override/embed/normal

③“視覺效果”描寫敘述屬性。調整的視覺效果塊內容。包含溢出行為。調整行為,能見度,動畫,變換。和過渡。

clip: rect(10px, 5px, 10px, 5px)
resize: auto; 常量:auto/both/horizontal/none/vertical
visibility: visible; 常量: collapse/hidden/visible
-webkit-transition: opacity 1s linear; 動畫效果 ease/linear/ease-in/ease-out/ease-in-out
-webkit-backface-visibility: visibler; 常量:visible(默認值)/hidden
-webkit-box-reflect: right 1px; 鏡向反轉
-webkit-box-reflect: below 4px -webkit-gradient(linear, left top, left bottom,
from(transparent), color-stop(0.5, transparent), to(white));
-webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,1)), to(rgba(0,0,0,0)));;   //CSS 遮罩/蒙板效果
-webkit-mask-attachment: fixed; 常量:fixed/scroll
-webkit-perspective: value; 常量:none(默認)
-webkit-perspective-origin: left top;
-webkit-transform: rotate(5deg);
-webkit-transform-style: preserve-3d; 常量:flat/preserve-3d; (2D 與3D)

④“生成的內容,自己主動編號。並列出”描寫敘述屬性,同意您更改內容的一個組成部分。創建自己主動編號的章節和標題。和操縱的風格清單的內容。

content: “Item” counter(section) ” “;
This resets the counter.
First section
>two section
three section
counter-increment: section 1;
counter-reset: section;

⑤“分頁媒體”描寫敘述性能與外觀的屬性。控制印刷版本號的網頁,如分頁符的行為。

page-break-after: auto; 常量:always/auto/avoid/left/right
page-break-before: auto; 常量:always/auto/avoid/left/right
page-break-inside: auto; 常量:auto/avoid

⑥“顏色和背景”描寫敘述屬性控制背景下的塊級元素和顏色的文本內容的組成部分。

-webkit-background-clip: content; 常量:border/content/padding/text
-webkit-background-origin: padding; 常量:border/content/padding/text
-webkit-background-size: 55px; 常量:length/length_x/length_y

⑦ “字型”的具體描寫敘述性質的文字字體的選擇范圍內的一個因素。

報告還描寫敘述屬性用於下載字體定義。

unicode-range: U+00-FF, U+980-9FF;

⑧“文本”描寫敘述屬性的特定文字樣式,間距和自己主動滾屏。

text-shadow: #00FFFC 10px 10px 5px;
text-transform: capitalize; 常量:capitalize/lowercase/none/uppercase
word-wrap: break-word; 常量:break-word/normal
-webkit-marquee: right large infinite normal 10s; 常量:direction(方向) increment(迭代次數) repetition(反復) style(樣式) speed(速度);
-webkit-marquee-direction: ahead/auto/backwards/down/forwards/left/reverse/right/up
-webkit-marquee-incrementt: 1-n/infinite(無窮次)
-webkit-marquee-speed: fast/normal/slow
-webkit-marquee-style: alternate/none/scroll/slide
-webkit-text-fill-color: #ff6600; 常量:capitalize, lowercase, none, uppercase
-webkit-text-security: circle; 常量:circle/disc/none/square
-webkit-text-size-adjust: none; 常量:auto/none;
-webkit-text-stroke: 15px #fff;
-webkit-line-break: after-white-space; 常量:normal/after-white-space
-webkit-appearance: caps-lock-indicator;
-webkit-nbsp-mode: space; 常量: normal/space
-webkit-rtl-ordering: logical; 常量:visual/logical
-webkit-user-drag: element; 常量:element/auto/none
-webkit-user-modify: read- only; 常量:read-write-plaintext-only/read-write/read-only
-webkit-user-select: text; 常量:text/auto/none

⑨“表格”描寫敘述的布局和設計性能表的具體內容。

-webkit-border-horizontal-spacing: 2px;
-webkit-border-vertical-spacing: 2px;
-webkit-column-break-after: right; 常量:always/auto/avoid/left/right
-webkit-column-break-before: right; 常量:always/auto/avoid/left/right
–webkit-column-break-inside: logical; 常量:avoid/auto
-webkit-column-count: 3; //分欄
-webkit-column-rule: 1px solid #fff;
style:dashed,dotted,double,groove,hidden,inset,none,outset,ridge,solid

⑩“用戶界面”描寫敘述屬性,涉及到用戶界面元素在瀏覽器中,如滾動文字區。滾動欄,等等。報告還描寫敘述屬性,范圍以外的網頁內容,如光標的標注樣式和顯示當您按住觸摸觸摸
目標,如在iPhone上的鏈接。

-webkit-box-align: baseline,center,end,start,stretch 常量:baseline/center/end/start/stretch
-webkit-box-direction: normal;常量:normal/reverse
-webkit-box-flex: flex_valuet
-webkit-box-flex-group: group_number
-webkit-box-lines: multiple; 常量:multiple/single
-webkit-box-ordinal-group: group_number
-webkit-box-orient: block-axis; 常量:block-axis/horizontal/inline-axis/vertical/orientation
–webkit-box-pack: alignment; 常量:center/end/justify/start

動畫過渡
這是 Webkit 中最具創新力的特性:使用過渡函數定義動畫。

-webkit-animation: title infinite ease-in-out 3s;
animation 有這幾個屬性:
-webkit-animation-name: //屬性名。就是我們定義的keyframes
-webkit-animation-duration:3s //持續時間
-webkit-animation-timing-function: //過渡類型:ease/ linear(線性) /ease-in(慢到快)/ease-out(快到慢) /ease-in-out(慢到快再到慢) /cubic-bezier
-webkit-animation-delay:10ms //動畫延遲(默認0)
-webkit-animation-iteration-count: //循環次數(默認1)。infinite 為無限
-webkit-animation-direction: //動畫方式:normal(默認 正向播放); alternate(交替方向。第偶數次正向播放,第奇數次反向播放)

這些相同是能夠簡寫的。

但真正讓我覺的非常爽的是keyframes。它能定義一個動畫的轉變過程供調用,過程為0%到100%或from(0%)到to(100%)。

簡單點說。僅僅要你有想法,你想讓元素在這個過程中以什么樣的方式改變都是非常easy的。

-webkit-transform: 類型(縮放scale/旋轉rotate/傾斜skew/位移translate)
scale(num,num) 放大倍率。scaleX 和 scaleY(3),能夠簡寫為:scale(* , *)
rotate(*deg) 轉動角度。rotateX 和 rotateY,能夠簡寫為:rotate(* , *)
Skew(*deg) 傾斜角度。skewX 和skewY,可簡寫為:skew(* , *)
translate(*,*) 坐標移動。translateX 和translateY,可簡寫為:translate(* , *)。

頁面描寫敘述

<link rel="apple-touch-icon-precomposed" href="http://www.xxx.com/App_icon_114.png" />
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="http://www.xxx.com/App_icon_72.png" />
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="http://www.xxx.com/App_icon_114.png" />

這個屬性是當用戶把連接保存到手機桌面時使用的圖標,假設不設置。則會用網頁的截圖。有了這,就能夠讓你的網頁像APP一樣存在手機里了

<link rel="apple-touch-startup-image" href="/img/startup.png" />

這個是APP啟動畫面圖片。用途和上面的相似,假設不設置,啟動畫面就是白屏,圖片像素就是手機全屏的像素

<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

這個描寫敘述是表示打開的web app的最上面的時間、信號欄是黑色的,當然也能夠設置其它參數,具體參數說明請參照:Safari HTML Reference - Supported Meta Tags

<meta name="apple-touch-fullscreen" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />

常見的 iPhone 和 Android 屏幕參數。

  • 設備 分辨率 設備像素比率
  • Android LDPI 320×240 0.75
  • Iphone 3 & Android MDPI 320×480 1
  • Android HDPI 480×800 1.5
  • Iphone 4 960×640 2.0

iPhone 4的一個 CSS 像素實際上表現為一塊 2×2 的像素。所以圖片像是被放大2倍一樣,模糊不清楚。

解決的方法:

1、頁面引用

<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 0.75)" href="ldpi.css" />
<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.0)" href="mdpi.css" />
<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.5)" href="hdpi.css" />
<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 2.0)" href="retina.css" />

2、CSS文件中

#header {
    background:url(mdpi/bg.png);
}

@media screen and (-webkit-device-pixel-ratio: 1.5) {
    /*CSS for high-density screens*/
    #header {
        background:url(hdpi/bg.png);
    }
}

移動 Web 開發經驗技巧

點擊與click事件

對於a標記的點擊導航,默認是在onclick事件中處理的。而移動client對onclick的響應相比PC瀏覽器有着明顯的幾百毫秒延遲。

在移動瀏覽器中對觸摸事件的響應順序應當是:

ontouchstart -> ontouchmove -> ontouchend -> onclick

因此,假設確實要加快對點擊事件的響應。就應當綁定ontouchend事件。

使用click會出現綁定點擊區域閃一下的情況,解決:給該元素一個樣式例如以下

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

假設不使用click,也不能簡單的用touchstart或touchend替代,須要用touchstart的模擬一個click事件,而且不能發生touchmove事件。或者用zepto中的tap(輕擊)事件。

body
{
    -webkit-overflow-scrolling: touch;
}

用iphone或ipad瀏覽非常長的網頁滾動時的滑動效果非常不錯吧?只是假設是一個div,然后設置 height:200px;overflow:auto;的話。能夠滾動可是全然沒有那滑動效果,非常郁悶吧?

我看到非常多站點為了實現這一效果,用了第三方類庫,最經常使用的是iscroll(包含新浪手機頁。百度等)
我一開始也使用,只是自從用了-webkit-overflow-scrolling: touch;樣式后,就全然能夠拋棄第三方類庫了,把它加在body{}區域,全部的overflow須要滾動的都能夠生效了。

另外有一篇比較全的移動端點擊解決方式 http://www.zhihu.com/question/28979857

鎖定 viewport

ontouchmove="event.preventDefault()" //鎖定viewport,不論什么屏幕操作不移動用戶界面(彈出鍵盤除外)。

利用 Media Query監聽

Media Query 相信大部分人已經使用過了。事實上 JavaScript能夠配合 Media Query這么用:

var mql = window.matchMedia("(orientation: portrait)");
mql.addListener(handleOrientationChange);
handleOrientationChange(mql); 
function handleOrientationChange(mql) {
  if (mql.matches) {
    alert('The device is currently in portrait orientation ')
  } else {
    alert('The device is currently in landscape orientation')
  }}

借助了 Media Query 接口做的事件監聽,所以非常強大!

也能夠通過獲取 CSS 值來使用 Media Query 推斷設備情況,詳情請看:JavaScript 依據 CSS Media Queries 推斷設備的方法

rem最佳實踐

rem是非常好用的一個屬性,能夠依據html來設定基准值,而且兼容性也非常不錯。只是有的時候還是須要對一些莫名其妙的瀏覽器優雅降級。下面是兩個實踐

  1. http://jsbin.com/vaqexuge/4/edit 這有個demo,發現chrome當font-size小於12時。rem會依照12來計算。因此設置基准值要考慮這一點
  2. 能夠用下面的代碼片段保證在低端瀏覽器下也不會出問題

    html { font-size: 62.5%; }
    body { font-size: 14px; font-size: 1.4rem; } /* =14px */
    h1 { font-size: 24px; font-size: 2.4rem; } /* =24px */

被點擊元素的外觀變化。能夠使用樣式來設定:

-webkit-tap-highlight-color: 顏色

檢測推斷 iPhone/iPod

開發特定設備的移動站點。首先要做的就是設備偵測了。

下面是使用Javascript偵測iPhone/iPod的UA,然后轉向到專屬的URL。

if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))) {
  if (document.cookie.indexOf("iphone_redirect=false") == -1) {
    window.location = "http://m.example.com";
  }
}

盡管Javascript是能夠在水果設備上運行的,可是用戶還是能夠禁用。它也會造成client刷新和額外的傳輸數據,所下面面是服務器端偵測和轉向:

if(strstr($_SERVER['HTTP_USER_AGENT'],'iPhone') || strstr($_SERVER['HTTP_USER_AGENT'],'iPod')) {
  header('Location: http://yoursite.com/iphone');
  exit();
}

阻止旋轉屏幕時自己主動調整字體大小

html, body, form, fieldset, p, div, h1, h2, h3, h4, h5, h6 {-webkit-text-size-adjust:none;}

模擬:hover偽類

由於iPhone並沒有鼠標指針,所以沒有hover事件。那么CSS :hover偽類就沒用了。可是iPhone有Touch事件,onTouchStart 相似 onMouseOver,onTouchEnd 相似 onMouseOut。所以我們能夠用它來模擬hover。使用Javascript:

var myLinks = document.getElementsByTagName('a');
for(var i = 0; i < myLinks.length; i++){
  myLinks[i].addEventListener(’touchstart’, function(){this.className = “hover”;}, false);
  myLinks[i].addEventListener(’touchend’, function(){this.className = “”;}, false);
}

然后用CSS添加hover效果:

a:hover, a.hover { /* 你的hover效果 */ }

這樣設計一個鏈接,感覺能夠更像button。

而且,這個模擬能夠用在不論什么元素上。

Flexbox 布局

Flex 模板和實例

深入了解 Flexbox 伸縮盒模型

CSS Flexbox Intro

http://www.w3.org/TR/css3-flexbox/

居中問題

居中是移動端跟pc端共同的噩夢。這里有兩種兼容性比較好的新方案。

  • table布局法

    .box{
    text-align:center;
    display:table-cell;
    vertical-align:middle;
    }

  • 老版本號flex布局法

    .box{
    display:-webkit-box;
    -webkit-box-pack: center;
    -webkit-box-align: center;
    text-align:center;
    }

以上兩種事實上各自是retchat跟ionic的布局基石。

這里有更具體的很多其它的選擇http://www.zhouwenbin.com/%E5%9E%82%E7%9B%B4%E5%B1%85%E4%B8%AD%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E6%B3%95/ 來自周文彬的博客

移動端實現標題文字截斷

http://www.75team.com/archives/611

處理 Retina 雙倍屏幕

(經典)Using CSS Sprites to optimize your website for Retina Displays

使用CSS3的background-size優化蘋果的Retina屏幕的圖像顯示

使用 CSS sprites 來優化你的站點在 Retina 屏幕下顯示

(案例)CSS IMAGE SPRITES FOR RETINA (HIRES) DEVICES

input類型為date情況下不支持placeholder(來自於江水)

這事實上是瀏覽器自己的處理。

由於瀏覽器會針對此類型 input 添加 datepicker 模塊。

對 input type date 使用 placeholder 的目的是為了讓用戶更准確的輸入日期格式。iOS 上會有 datepicker 不會顯示 placeholder 文字。可是為了統一表單外觀,往往須要顯示。

Android 部分機型沒有 datepicker 也不會顯示 placeholder 文字。

桌面端(Mac)

  • Safari 不支持 datepicker,placeholder 正常顯示。
  • Firefox 不支持 datepicker,placeholder 正常顯示。
  • Chrome 支持 datepicker,顯示 年、月、日 格式,忽略 placeholder。

移動端

  • iPhone5 iOS7 有 datepicker 功能,可是不顯示 placeholder。

  • Andorid 4.0.4 無 datepicker 功能。不顯示 placeholder

解決方法:

<input placeholder="Date" class="textbox-n" type="text" onfocus="(this.type='date')"  id="date"> 

由於text是支持placeholder的。

因此當用戶focus的時候自己主動把type類型改變為date,這樣既有placeholder也有datepicker了

推斷照片的橫豎排列

有這樣一種需求,須要推斷用戶照片是橫着拍出來的還是豎着拍出來的,這里須要使用照片得exif信息:

$("input").change(function() {
    var file = this.files[0];
    fr   = new FileReader;

    fr.onloadend = function() {
        var exif = EXIF.readFromBinaryFile(new BinaryFile(this.result));
        alert(exif.Orientation);
    };

    fr.readAsBinaryString(file);
});

能夠使用這兩個庫 來取exif信息http://www.nihilogic.dk/labs/binaryajax/binaryajax.js http://www.nihilogic.dk/labs/exif/exif.js

Android上當viewport的width大於device-width時出現文字無故折行的解決的方法

http://www.iunbug.com/archives/2013/04/23/798.html

白屏解決與優化方案

當前非常多無線頁面都使用前端模板進行數據渲染。那么在糟糕的網速情況下,一進去頁面,看到的不是白屏就是 loading,這成為白屏問題。

此問題發生的原因基本能夠歸結為網速跟靜態資源

1、css文件載入須要一些時間,在載入的過程中頁面是空白的。 解決:能夠考慮將css代碼前置和內聯。
2、首屏無實際的數據內容,等待異步載入數據再渲染頁面導致白屏。

解決:在首屏直接同步渲染html,興許的滾屏等再採用異步請求數據和渲染html。
3、首屏內聯js的運行會堵塞頁面的渲染。 解決:盡量不在首屏html代碼中放置內聯腳本。(來自翔歌)

解決方式

根本原因是client渲染的無力,因此最簡單的方法是在服務器端,使用模板引擎渲染全部頁面。同一時候

1降低文件載入體積,如html壓縮。js壓縮
2加快js運行速度 比方常見的無限滾動的頁面,能夠使用js先渲染一個屏幕范圍內的東西
3提供一些友好的交互,比方提供一些假的滾動欄
4使用本地存儲處理靜態文件。

怎樣實現打開已安裝的app,若未安裝則引導用戶安裝?

來自 http://gallery.kissyui.com/redirectToNative/1.2/guide/index.html kissy mobile
通過iframe src發送請求打開app自己定義url scheme,如taobao://home(淘寶首頁) 、etao://scan(一淘掃描));
假設安裝了client則會直接喚起,直接喚起后,之前瀏覽器窗體(或者掃碼工具的webview)推入后台;
假設在指定的時間內client沒有被喚起,則js重定向到app下載地址。
大概實現代碼例如以下

goToNative:function(){

    if(!body) {
            setTimeout(function(){
                doc.body.appendChild(iframe);
            }, 0);
        } else {
            body.appendChild(iframe);
        }

setTimeout(function() {
            doc.body.removeChild(iframe);
            gotoDownload(startTime);//去下載,下載鏈接通常是itunes app store或者apk文件鏈接
            /**
             * 測試時間設置小於800ms時,在android下的UC瀏覽器會打開native app時並下載apk,
             * 測試android+UC下打開native的時間最好大於800ms;
             */
        }, 800);
}

須要注意的是 假設是android chrome 25版本號以后。在iframe src不會發送請求。
原因例如以下https://developers.google.com/chrome/mobile/docs/intents 。通過location href使用intent機制拉起client可行而且當前頁面不跳轉。

window.location = 'intent://' + schemeUrl + '#Intent;scheme=' + scheme + ';package=' + self.package + ';end';

補充一個來自三水清的具體解說 http://js8.in/2013/12/16/ios%E4%BD%BF%E7%94%A8schema%E5%8D%8F%E8%AE%AE%E8%B0%83%E8%B5%B7app/

active的兼容(來自薛端陽)

今天發現。要讓a鏈接的CSS active偽類生效,僅僅須要給這個a鏈接的touch系列的隨意事件touchstart/touchend綁定一個空的匿名方法就可以hack成功

<style>
a {
color: #000;
}
a:active {
color: #fff;
}
</style>
<a herf=”asdasd”>asdasd</a>
<script>
var a=document.getElementsByTagName(‘a’);
for(var i=0;i<a.length;i++){
a[i].addEventListener(‘touchstart’,function(){},false);
}
</script>

消除transition閃屏

兩個方法:使用css3動畫的時盡量利用3D加速,從而使得動畫變得流暢。動畫過程中的動畫閃白能夠通過 backface-visibility 隱藏。

-webkit-transform-style: preserve-3d;
/*設置內嵌的元素在 3D 空間怎樣呈現:保留 3D*/
-webkit-backface-visibility: hidden;
/*(設置進行轉換的元素的背面在面對用戶時是否可見:隱藏)*/

測試是否支持svg圖片

document.implementation.hasFeature("http:// www.w3.org/TR/SVG11/feature#Image", "1.1")

考慮兼容“隱私模式”(from http://blog.youyo.name/archives/smarty-phones-webapp-deverlop-advance.html)

ios的safari提供一種“隱私模式”,假設你的webapp考慮兼容這個模式,那么在使用html5的本地存儲的一種————localStorage時,可能由於“隱私模式”下沒有權限讀寫localstorge而使代碼拋出錯誤。導致興許的js代碼都無法運行了。

既然在safari的“隱私模式”下,沒有調用localStorage的權限,首先想到的是先推斷是否支持localStorage,代碼例如以下:

if('localStorage' in window){
    //須要使用localStorage的代碼寫在這
}else{
    //不支持的提示和向下兼容代碼
}

測試發現,即使在safari的“隱私模式”下,’localStorage’ in window的返回值依舊為true,也就是說。if代碼塊內部的代碼依舊會運行,問題沒有得到解決。


接下來僅僅能相當使用try catch了。盡管這是一個不太推薦被使用的方法,使用try catch捕獲錯誤,使興許的js代碼能夠繼續運行。代碼例如以下:

try{
    if('localStorage' in window){
         //須要使用localStorage的代碼寫在這
    }else{
         //不支持的提示和向下兼容代碼
    }
}catch(e){
    // 隱私模式相關提示代碼和不支持的提示和向下兼容代碼
}

所以。提醒大家注意,在須要兼容ios的safari的“隱私模式”的情況下,本地存儲相關的代碼須要使用try catch包裹並降級兼容。

安卓手機點擊鎖定頁面效果問題

有些安卓手機。頁面點擊時會停止頁面的javascript,css3動畫等的運行,這個比較蛋疼。

只是能夠用阻止默認事件解決。具體見
http://stackoverflow.com/questions/10246305/android-browser-touch-events-stop-display-being-updated-inc-canvas-elements-h

function touchHandlerDummy(e)
{
    e.preventDefault();
    return false;
}
document.addEventListener("touchstart", touchHandlerDummy, false);
document.addEventListener("touchmove", touchHandlerDummy, false);
document.addEventListener("touchend", touchHandlerDummy, false);

消除ie10里面的那個叉號

IE Pseudo-elements

input:-ms-clear{display:none;}

關於ios與os端字體的優化(橫豎屏會出現字體加粗不一致等)

mac下網頁中文字體優化

UIWebView font is thinner in portrait than landscape

推斷用戶是否是“將網頁加入到主屏后,再從主屏幕打開這個網頁”的

navigator.standalone

隱藏地址欄 & 處理事件的時候,防止滾動欄出現:

// 隱藏地址欄  & 處理事件的時候 ,防止滾動欄出現
addEventListener('load', function(){
        setTimeout(function(){ window.scrollTo(0, 1); }, 100);
});

ios7 能夠通過meta標簽的minimal來隱藏地址欄了

http://darkblue.sdf.org/weblog/ios-7-dot-1-mobile-safari-minimal-ui.html

推斷是否為iPhone:

// 推斷是否為 iPhone :
function isAppleMobile() {
    return (navigator.platform.indexOf('iPhone') != -1);
};

localStorage:

var v = localStorage.getItem('n') ?

localStorage.getItem('n') : ""; // 假設名稱是 n 的數據存在 ,則將其讀出 ,賦予變量 v 。 localStorage.setItem('n', v); // 寫入名稱為 n、值為 v 的數據 localStorage.removeItem('n'); // 刪除名稱為 n 的數據

使用特殊鏈接:

假設你關閉自己主動識別后 。又希望某些電話號碼能夠鏈接到 iPhone 的撥號功能 。那么能夠通過這樣來聲明電話鏈接 ,

<a href="tel:12345654321">打電話給我</a>
<a href="sms:12345654321">發短信</a>

或用於單元格:

<td onclick="location.href='tel:122'">

自己主動大寫與自己主動修正

要關閉這兩項功能。能夠通過autocapitalize 與autocorrect 這兩個選項:

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

不讓 Android 識別郵箱

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

禁止 iOS 彈出各種操作窗體

-webkit-touch-callout:none

禁止用戶選中文字

-webkit-user-select:none

動畫效果中,使用 translate 比使用定位性能高

Why Moving Elements With Translate() Is Better Than Pos:abs Top/left

拿到滾動欄

window.scrollY
window.scrollX

比方要綁定一個touchmove的事件。正常的情況下相似這樣(來自呼吸二氧化碳)

$('div').on('touchmove', function(){
//.….code
{});

而假設中間的code須要處理的東西多的話,fps就會下降影響程序順滑度,而假設改成這樣

$('div').on('touchmove', function(){
setTimeout(function(){
//.….code
},0);
{});

把代碼放在setTimeout中。會發現程序變快.

關於 iOS 系統中。Web APP 啟動圖片在不同設備上的適應性設置

http://stackoverflow.com/questions/4687698/mulitple-apple-touch-startup-image-resolutions-for-ios-web-app-esp-for-ipad/10011893#10011893

position:sticky與position:fixed布局

http://www.zhouwenbin.com/positionsticky-%E7%B2%98%E6%80%A7%E5%B8%83%E5%B1%80/
http://www.zhouwenbin.com/sticky%E6%A8%A1%E6%8B%9F%E9%97%AE%E9%A2%98/

關於 iOS 系統中,中文輸入法輸入英文時,字母之間可能會出現一個六分之中的一個空格

能夠通過正則去掉

this.value = this.value.replace(/\u2006/g, '');

關於android webview中,input元素輸入時出現的怪異情況

見下圖

怪異圖

Android Web 視圖,至少在 HTC EVO 和三星的 Galaxy Nexus 中。文本輸入框在輸入時表現的就像占位符。情況為一個相似水印的東西在用戶輸入區域。一旦用戶開始輸入便會消失(見圖片)。

在 Android 的默認樣式下當輸入框獲得焦點后,若存在一個絕對定位或者 fixed 的元素。布局會被破壞,其它元素與系統輸入字段會發生重疊(如搜索圖標將消失為搜索字段)。能夠觀察到布局與原始輸入字段有偏差(見截圖)。

這是一個相當復雜的問題,下面簡單布局能夠重現這個問題:

<label for="phone">Phone: *</label>
<input type="tel" name="phone" id="phone" minlength="10" maxlength="10" inputmode="latin digits" required="required" />

解決方法

-webkit-user-modify: read-write-plaintext-only

具體參考http://www.bielousov.com/2012/android-label-text-appears-in-input-field-as-a-placeholder/
注意,該屬性會導致中文不能輸入詞組,僅僅能單個字。感謝鬼哥與飛(游勇飛)貢獻此問題與解決方式

另外,在position:fixed后的元素里,盡量不要使用輸入框。很多其它的bug可參考
http://www.cosdiv.com/page/M0/S882/882353.html

依舊無法解決(摩托羅拉ME863手機),則使用input:text類型而非password類型,並設置其設置 -webkit-text-security: disc; 隱藏輸入密碼從而解決。

JS動態生成的select下拉菜單在Android2.x版本號的默認瀏覽器里不起作用

解決方法刪除了overflow-x:hidden; 然后在JS生成下來菜單之后focus聚焦,這兩步操作之后攻克了問題。

(來自島都-小Qi)

參考http://stackoverflow.com/questions/4697908/html-select-control-disabled-in-android-webview-in-emulator

Andriod 上去掉語音輸入button

input::-webkit-input-speech-button {display: none}

IE10 的特殊鼠標事件

IE10 事件監聽

iOS 輸入框最佳實踐

Mobile-friendly input of a digits + spaces string (a credit card number)

HTML5 input type number vs tel

iPhone: numeric keyboard for text input

Text Programming Guide for iOS - Managing the Keyboard

HTML5 inputs and attribute support

往返緩存問題

點擊瀏覽器的回退,有時候不會自己主動運行js。特別是在mobilesafari中。

這與往返緩存(bfcache)有關系。

有非常多hack的處理方法。能夠參考

http://stackoverflow.com/questions/24046/the-safari-back-button-problem

http://stackoverflow.com/questions/11979156/mobile-safari-back-button

不暫停的計時器(safari的進程凍結)

https://www.imququ.com/post/ios-none-freeze-timer.html
或者能夠用postmessage方式:
主頁面:

    // 解決ios safari tab在后台會遭遇進程凍結問題
    // http://www.apple.com/safari/#gallery-icloud-tabs
    // Safari takes advantage of power-saving technologies such as App Nap, which puts background Safari tabs into a low-power state until you start using them again. In addition, Safari Power Saver conserves battery life by intelligently pausing web videos and other plug‑in content when they’re not front and center on the web pages you visit. All told, Safari on OS X Mavericks lets you browse up to an hour longer than with Chrome or Firefox.1
    var work;
    function startWorker() {
        if (typeof(Worker) !== "undefined") {
            if (typeof(work) == "undefined") {
                work = new Worker("/workers.js");
            }
            work.onmessage = function(event) {
                // document.getElementById("result-count").innerHTML = event.data.count;
                // document.getElementById("result-url").innerHTML = event.data.targetURL;
                if (target && event.data.targetURL != "") target.location.href = event.data.targetURL;
            };
        } else {
            console.log('does not support Web Workers...');
        }
    }

    function stopWorker() {
        work.terminate();
    }

    startWorker();

worker:

// 解決ios safari tab在后台會遭遇進程凍結問題
// http://www.apple.com/safari/#gallery-icloud-tabs
// Safari takes advantage of power-saving technologies such as App Nap, which puts background Safari tabs into a low-power state until you start using them again. In addition, Safari Power Saver conserves battery life by intelligently pausing web videos and other plug‑in content when they’re not front and center on the web pages you visit. All told, Safari on OS X Mavericks lets you browse up to an hour longer than with Chrome or Firefox.1

importScripts('/socket.io/socket.io.js');

var count = 0,
    targetURL = ''
    ; 

var socket = io.connect('/');
socket.on('navigate', function (data) {
  count = count++;
  postMessage({targetURL:data.url,count:count});
});

Web移動端Fixed布局的解決方式

http://efe.baidu.com/blog/mobile-fixed-layout/

ios上background-attachment:fixed不能正常工作

參考 http://stackoverflow.com/questions/20443574/fixed-background-image-with-ios7

怎樣讓音頻跟視頻在ios跟android上自己主動播放

<audio autoplay ><source  src="audio/alarm1.mp3" type="audio/mpeg"></audio>

系統默認情況下 audio的autoplay屬性是無法生效的,這也是手機為節省用戶流量做的考慮。
假設必須要自己主動播放。有兩種方式能夠解決。

1.捕捉一次用戶輸入后,讓音頻載入,下次就可以播放。

//play and pause it once
document.addEventListener('touchstart', function () {
    document.getElementsByTagName('audio')[0].play();
    document.getElementsByTagName('audio')[0].pause();
});

這樣的方法須要捕獲一次用戶的點擊事件來促使音頻跟視頻載入。當載入后,你就能夠用javascript控制音頻的播放了,如調用audio.play()

2.利用iframe載入資源

var ifr=document.createElement("iframe");
ifr.setAttribute('src', "http://mysite.com/myvideo.mp4");
ifr.setAttribute('width', '1px');
ifr.setAttribute('height', '1px');
ifr.setAttribute('scrolling', 'no');
ifr.style.border="0px";
document.body.appendChild(ifr);

這樣的方式事實上跟第一種原理是一樣的。當資源載入了你就能夠控制播放了,可是這里使用iframe來載入。相當於直接觸發資源載入。
注意,使用創建audio標簽並讓其載入的方式是不可行的。
慎用這樣的方法,會對用戶造成非常糟糕的影響。

iOS 6 跟 iPhone 5 的那些事

IP5 的媒體查詢

@media (device-height: 568px) and (-webkit-min-device-pixel-ratio: 2) {

/* iPhone 5 or iPod Touch 5th generation */

}

使用媒體查詢。提供不同的啟動圖片:

<link href="startup-568h.png" rel="apple-touch-startup-image" media="(device-height: 568px)">
<link href="startup.png" rel="apple-touch-startup-image" sizes="640x920" media="(device-height: 480px)">

拍照上傳

<input type=file accept="video/*">
<input type=file accept="image/*">

不支持其它類型的文件 ,如音頻,Pages文檔或PDF文件。

也沒有getUserMedia攝像頭的實時流媒體支持。

能夠使用的 HTML5 高級 api

  • multipart POST 表單提交上傳
  • XMLHttpRequest 2 AJAX 上傳(甚至進度支持)
  • 文件 API ,在 iOS 6 同意 JavaScript 直接讀取的字節數和client操作文件。

智能應用程序橫幅

有了智能應用程序橫幅,當站點上有一個相關聯的本機應用程序時,Safari瀏覽器能夠顯示一個橫幅。

假設用戶沒有安裝這個應用程序將顯示“安裝”button,或已經安裝的顯示“查看”button可打開它。

在 iTunes Link Maker 搜索我們的應用程序和應用程序ID。

<meta name="apple-itunes-app" content="app-id=9999999">

能夠使用 app-argument 提供字符串值。假設參加iTunes聯盟計划,能夠加入元標記數據

<meta name="apple-itunes-app" content="app-id=9999999, app-argument=xxxxxx">

<meta name="apple-itunes-app" content="app-id=9999999, app-argument=xxxxxx, affiliate-data=partnerId=99&siteID=XXXX">

橫幅須要156像素(設備是312 hi-dpi)在頂部,直到用戶在下方點擊內容或關閉button。你的站點才會展現全部的高度。 它就像HTML的DOM對象。但它不是一個真正的DOM。

CSS3 濾鏡

-webkit-filter: blur(5px) grayscale (.5) opacity(0.66) hue-rotate(100deg);

交叉淡變

background-image: -webkit-cross-fade(url("logo1.png"), url("logo2.png"), 50%);

Safari中的全屏幕

除了chrome-less 主屏幕meta標簽,如今的iPhone和iPod Touch(而不是在iPad)支持全屏幕模式的窗體。 沒有辦法強制全屏模式。它須要由用戶啟動(工具欄上的最后一個圖標)。

須要引導用戶按下屏幕上的全屏圖標來激活全屏效果。 能夠使用onresize事件檢測是否用戶切換到全屏幕。

支持requestAnimationFrameAPI

支持image-set,retina屏幕的利器

-webkit-image-set(url(low.png) 1x, url(hi.jpg) 2x)

應用程序緩存限制添加至25MB。

Web View(pseudobrowsers,PhoneGap/Cordova應用程序。嵌入式瀏覽器) 上Javascript運行比Safari慢3.3倍(或者說,Nitro引擎在Safari瀏覽器是Web應用程序是3.3倍速度)。

autocomplete屬性的輸入遵循DOM規范

來自DOM4的Mutation Observers已經實現。 您能夠使用WebKitMutationObserver構造器捕獲DOM的變化

Safari不再總是對用 -webkit-transform:preserve-3d 的元素創建硬件加速

支持window.selection 的Selection API

Canvas更新 :createImageData有一個參數,如今有兩個新的功能做好准備。用webkitGetImageDataHD和webkitPutImageDataHD提供高分辨率圖像 。

更新SVG處理器和事件構造函數

IOS7的大更新

iOS 7 的 Safari 和 HTML5:問題。變化和新 API(張金龍翻譯)

iOS 7 的一些坑(英文)

ios7的一些坑2(英文)

webview相關

Cache開啟和設置

browser.getSettings().setAppCacheEnabled(true);
browser.getSettings().setAppCachePath("/data/data/[com.packagename]/cache");
browser.getSettings().setAppCacheMaxSize(5*1024*1024); // 5MB

LocalStorage相關設置

browser.getSettings().setDatabaseEnabled(true);
browser.getSettings().setDomStorageEnabled(true);
String databasePath = browser.getContext().getDir("databases", Context.MODE_PRIVATE).getPath();
browser.getSettings().setDatabasePath(databasePath);//Android webview的LocalStorage有個問題,關閉APP或者重新啟動后,就清楚了,所以須要browser.getSettings().setDatabase相關的操作,把LocalStoarge存到DB中

myWebView.setWebChromeClient(new WebChromeClient(){
    @Override
    public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize, long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater)
    {
        quotaUpdater.updateQuota(estimatedSize * 2);
    }
}

瀏覽器自帶縮放button取消顯示

browser.getSettings().setBuiltInZoomControls(false);

幾個比較好的實踐

使用localstorage緩存html

使用lazyload。還要記得lazyload占位圖盡管小,可是最好能提前載入到緩存

延時載入運行js

主要原因就在於Android Webview的onPageFinished事件,Android端通常是用這個事件來標識頁面載入完畢並顯示的。也就是說在此之前,會一直loading,可是Android的OnPageFinished事件會在Javascript腳本運行完畢之后才會觸發。假設在頁面中使用JQuery。會在處理完DOM對象,運行完$(document).ready(function() {});事件自會后才會渲染並顯示頁面。

manifest與緩存相關:

http://www.alloyteam.com/2013/12/web-cache-6-hybrid-app-tailored-cache/
相關解決方式
http://mt.tencent.com/

移動端調適篇

手機抓包與配host

在PC上。我們能夠非常方便地配host。可是手機上怎樣配host,這是一個問題。

這里主要使用fiddler和遠程代理。實現手機配host的操作。具體操作例如以下:

首先。保證PC和移動設備在同一個局域網下;

PC上開啟fiddler。並在設置中勾選“allow remote computers to connect”

  1. 首先,保證PC和移動設備在同一個局域網下;

  2. PC上開啟fiddler,並在設置中勾選“allow remote computers to connect”
    fiddler

  3. 手機上設置代理。代理IP為PC的IP地址,端口為8888(這是fiddler的默認端口)。

    通常手機上能夠直接設置代理,假設沒有。能夠去下載一個叫ProxyDroid的APP來實現代理的設置。

  4. 此時你會發現,用手機上網。走的事實上是PC上的fiddler。全部的請求包都會在fiddler中列出來,配合willow使用,就可以實現配host,甚至是反向代理的操作。

也能夠用CCProxy之類軟件,另一種方法就是買一個隨身wifi,然后手機連接就能夠了。

高級抓包

iPhone上使用Burp Suite捕捉HTTPS通信包方法

mobile app 通信分析方法小議(iOS/Android)

實時抓取移動設備上的通信包(ADVsock2pipe+Wireshark+nc+tcpdump)

靜態資源緩存問題

一般用代理軟件代理過來的靜態資源能夠設置nocache避免緩存,可是有的手機比較詭異,會一直緩存住css等資源文件。由於靜態資源一般都是用版本號號管理的,我們以charles為樣例來處理這個問題

charles 選擇靜態的html頁面文件-saveResponse。

之后把這個文件保存一下。改動一下版本號號。

之后繼續發請求,
剛才的html頁面文件 右鍵選擇 –map local 選擇我們改動過版本號號的html文件即ok。這事實上也是fiddler遠程映射並改動文件的一個應用場景。

安卓模擬器和真機差別

http://www.farsight.com.cn/news/emb105.htm

http://testerhome.com/topics/388

http://www.cnblogs.com/zdz8207/archive/2012/01/30/2332436.html

移動瀏覽器篇

微信瀏覽器

微信瀏覽器的各種bug匯總 (x5內核) http://www.qianduan.net/qqliu-lan-qi-x5nei-he-wen-ti-hui-zong/

由於微信瀏覽器屏蔽了一部分鏈接圖片,所以須要引導用戶去打開新頁面。能夠用下面方式推斷微信瀏覽器的ua

function is_weixn(){
    var ua = navigator.userAgent.toLowerCase();
    if(ua.match(/MicroMessenger/i)=="micromessenger") {
        return true;
    } else {
        return false;
    }
}

后端推斷也非常easy。比方php

function is_weixin(){
    if ( strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false ) {
            return true;
    }  
    return false;
}

https://github.com/maxzhang/maxzhang.github.com/issues/31 微信瀏覽器踩坑,來自maxZhang https://github.com/maxzhang

【UC瀏覽器】video標簽脫離文檔流

場景:標簽的父元素(祖輩元素)設置transform樣式后。標簽會脫離文檔流。

測試環境:UC瀏覽器 8.7/8.6 + Android 2.3/4.0 。

Demo:http://t.cn/zj3xiyu

解決方式:不使用transform屬性。translate用top、margin等屬性替代。

【UC瀏覽器】video標簽總在最前

場景:標簽總是在最前(能夠理解為video標簽的z-index屬性是Max)。

測試環境:UC瀏覽器 8.7/8.6 + Android 2.3/4.0 。

【UC瀏覽器】position:fixed 屬性在UC瀏覽器的奇葩現象

場景:設置了position: fixed 的元素會遮擋z-index值更高的同輩元素。

   在8.6的版本號,這個情況直接出現。

   在8.7之后的版本號,當同輩元素的height大於713這個「奇妙」的數值時,才會被遮擋。

測試環境:UC瀏覽器 8.8_beta/8.7/8.6 + Android 2.3/4.0 。

Demo:http://t.cn/zYLTSg6

【QQ手機瀏覽器】不支持HttpOnly

場景:帶有HttpOnly屬性的Cookie。在QQ手機瀏覽器版本號從4.0開始失效。

JavaScript能夠直接讀取設置了HttpOnly的Cookie值。

測試環境:QQ手機瀏覽器 4.0/4.1/4.2 + Android 4.0 。

【MIUI原生瀏覽器】瀏覽器地址欄hash不改變

場景:location.hash 被賦值后,地址欄的地址不會改變。

   但實際上 location.href 已經更新了,通過JavaScript能夠順利獲取到更新后的地址。

   盡管不影響正常訪問。但用戶無法將訪問過程中改變hash后的地址存為書簽。

測試環境:MIUI 4.0

【Chrome Mobile】fixed元素無法點擊

場景:父元素設置position: fixed;

   子元素設置position: absolute;

   此時,假設父元素/子元素還設置了overflow: hidden 則出現“父元素遮擋該子元素“的bug。

   視覺(view)層並沒有出現遮擋,僅僅是無法觸發綁定在該子元素上的事件。可理解為:「看到點不到」。

補充: 頁面往下滾動,觸發position: fixed;的特性時。才會出現這個bug,在最頂不會出現。

測試平台: 小米1S,Android4.0的Chrome18

demo: http://maplejan.sinaapp.com/demo/fixed_chromemobile.html

解決的方法: 把父元素和子元素的overflow: hidden去掉。

以上來源於 http://www.cnblogs.com/maplejan/archive/2013/04/26/3045928.html

庫的使用實踐

zepto.js

zepto的一篇使用注意點解說

zepto的著名的tap“點透”bug

zepto源代碼凝視

使用zeptojs內嵌到android webview影響正常滾動時

https://github.com/madrobby/zepto/blob/master/src/touch.js 去掉61行,事實上就是使用原生的滾動

iscroll4

iscroll4 的幾個bug(來自 http://www.mansonchor.com/blog/blog_detail_64.html 內有具體解說)

1.滾動容器點擊input框、select等表單元素時沒有響應】

onBeforeScrollStart: function (e) { e.preventDefault(); }

改為

onBeforeScrollStart: function (e) { var nodeType = e.explicitOriginalTarget © e.explicitOriginalTarget.nodeName.toLowerCase():(e.target © e.target.nodeName.toLowerCase():'');if(nodeType !='select'&& nodeType !='option'&& nodeType !='input'&& nodeType!='textarea') e.preventDefault(); }

2.往iscroll容器內加入內容時,容器閃動的bug

源代碼的

has3d = 'WebKitCSSMatrix' in window && 'm11' in new WebKitCSSMatrix()

改成

has3d = false

在配置iscroll時,useTransition設置成false

3.過長的滾動內容,導致卡頓和app直接閃退

  1. 不要使用checkDOMChanges。盡管checkDOMChanges非常方便,定時檢測容器長度是否變化來refresh,但這也意味着你要消耗一個Interval的內存空間
  2. 隱藏iscroll滾動欄,配置時設置hScrollbar和vScrollbar為false。
  3. 不得已的情況下,去掉各種效果,momentum、useTransform、useTransition都設置為false

4.左右滾動時,不能正確響應正文上下拉動

iscroll的閃動問題也與渲染有關系,能夠參考
運用webkit繪制渲染頁面原理解決iscroll4閃動的問題
iscroll4升級到5要注意的問題

iscroll或者滾動類框架滾動時不點擊的方法

能夠使用下面的解決方式(利用data-setapi)

<a ontouchmove="this.s=1" ontouchend="this.s || window.open(this.dataset.href),this.s=0" target="_blank" data-href="http://www.hao123.com/topic/pig">黃浦江死豬之謎</a>

也能夠用這樣的方法

    $(document).delegate('[data-target]', 'touchmove', function () {
        $(this).attr('moving','moving');

    })


    $(document).delegate('[data-target]', 'touchend', function () {
        if ($(this).attr('moving') !== 'moving') {
         //做你想做的。

。 $(this).attr('moving', 'notMoving'); } else { $(this).attr('moving', 'notMoving'); } })

移動端字體問題

知乎專欄 - [無線手冊-4] dp、sp、px傻傻分不清楚[完整]

Resolution Independent Mobile UI

Pixel density, retina display and font-size in CSS

Device pixel density tests

跨域問題

手機瀏覽器也是瀏覽器,在ajax調用外部api的時候也存在跨域問題。

當然利用 PhoneGap 打包后。由於協議不一樣就不存在跨域問題了。


但頁面通常是須要跟后端進行調試的。通常會報相似

XMLHttpRequest cannot load XXX
Origin null is not allowed by Access-Control-Allow-Origin.

以及

XMLHttpRequest cannot load http://. Request header field Content-Type is not allowed by Access-Control-Allow-Headers."

這時候能夠讓后端加上兩個http頭

Access-Control-Allow-Origin "*"
Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"

第一個頭能夠避免跨域問題,第二個頭能夠方便ajax請求設置content-type等配置項

這個會存在一些安全問題,能夠參考這個問題的討論 http://www.zhihu.com/question/22992229

PhoneGap 部分

http://snoopyxdy.blog.163.com/blog/static/60117440201432491123551 這里有一大堆snoopy總結的phonggap開發坑

Should not happen: no rect-based-test nodes found

在 Android 項目中的 assets 中的 HTML 頁面中加入下面代碼,便可解決問題

window,html,body{
    overflow-x:hidden !important;
    -webkit-overflow-scrolling: touch !important;
    overflow: scroll !important;
}

參考:

http://stackoverflow.com/questions/12090899/android-webview-jellybean-should-not-happen-no-rect-based-test-nodes-found

拿聯系人的時候報 ContactFindOptions is not defined

出現這個問題可能是由於 Navigator 取 contacts 時綁定的 window.onload

注意使用 PhoneGap 的 API 時,一定要在 devicereay 事件的處理函數中使用 API

document.addEventListener("deviceready", onDeviceReady, false);

    function onDeviceReady() {    
        callFetchContacts();
    }

function callFetchContacts(){
    var options = new ContactFindOptions();
    options.multiple = true;
    var fields       = ["displayName", "name","phoneNumbers"];
    navigator.contacts.find(fields, onSuccess, onError,options);  
    }

原文鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM