移動Web應用開發入門指南——兼容篇

兼容篇

兼容篇是我最想寫的一部分,在這以前也總結過不少關於移動開發的兼容問題與解決方案。對於移動Web開發來講,兼容是開發重心,一般要花費30%甚至更多的時間去處理一些兼容問題,甚至時間花掉了,問題依然沒法解決。css

相比PC Web開發,移動開發的兼容性須要考慮的問題更復雜,我本身花了一個圖:html

圖13
13前端

在上圖中,我列了兩個維度:標準支持和個性化,我以爲這兩個維度能很好的體現PC與移動在兼容方面的差別。android

PC Web開發中,更多時候是在處理對標準支持程度的兼容問題,問題類型相對比較單一。在進入到IE9+時代,對HTML5特性與其餘標準支持已經愈來愈好,前端工程師已經得到了很大的解脫,可能描述得有必定的片面性,但差很少就是這樣。git

反觀移動端,還處於初級階段,相比PC瀏覽器來講,移動瀏覽器對標準的支持起步較高,從Android2.1+就已經支持了很大一部分的HTML5基礎功能,對ECMAScript 5的支持更是好,但這並不表明移動端的兼容性就很是的好處理。如上面那張圖,移動瀏覽器的個性十足,各個廠商都有本身特有的東西,這就給移動開發的兼容性帶來了十分大的挑戰。程序員

移動Web開發的兼容問題主要能夠從如下幾個層面來理解:github

  • 設備差別致使的兼容問題。
  • 操做系統差別致使的兼容問題。
  • 瀏覽器差別致使的兼容問題。

這三種差別,依次是設備 < 操做系統 < 瀏覽器,越接近應用層,須要處理的兼容問題越多。web

設備差別

可能有些人不解,爲何設備差別會致使兼容問題呢?其實在前面的交互篇就已經有提到移動設備的物理屬性的差別,這就直接致使了在移動Web開發的兼容問題。好比有些比較老舊設備的觸摸屏是不支持多點觸控的,只能捕獲單點,這就使得一些須要多點觸摸的應用場景出現兼容問題,好比圖片的放大、縮小。相似這種硬件缺胳膊少腿的問題是硬傷,沒法解決,通常遇到了也只能忽略,但能夠考慮給用戶一個提示。固然時代在變化,並且變化得很快,這樣的手機畢竟只是少數,就像拋棄IE6同樣拋棄它吧。瀏覽器

另一個問題就是devicePixelRatio(設備像素比)的問題,在前面視覺篇分享過兩篇文章,能夠拿到這再分享一次:微信

devicePixelRatio主要影響的是圖片顯示的問題,devicePixelRatio的發展有兩個趨勢:

  • 老舊設備,devicePixelRatio較低,比較奇葩的devicePixelRatio==1.5這樣的值,可能致使圖片顯示鋸齒;
  • 新設備,屏幕分辨率在往2k時代發展,devicePixelRatio==3甚至大於3,因此圖片顯示可能會比較虛;

在沒有特殊要求的狀況下,通常移動端是不對圖片作特殊處理的,統一都是使用2x大小的圖片。處理時通常分爲兩種狀況:

直接引用圖片<img src="xxx.png">,直接使用2x大小的圖片,將圖片高寬設置爲物理像素的1/2既可。

另外一種情形就是最多見的背景圖,將background-size設置爲物理像素的1/2。好比圖片物理像素爲200*200,代碼以下:

<style>
#b1 {
    width: 100px;
    height: 100px;
    background: url("xxx.png") no-repeat;
    -webkit-background-size: 100px 100px;
    background-size: 100px 100px;
}
</style>
<div id="b1"></div>

如遇到一些須要背景圖自適配寬度的應用場景,可使用background-size: cover;

操做系統差別

操做系統差別與瀏覽器差別是會產生重疊知識點,操做系統差別更偏向於描述因爲iOS、Android或其餘系統差別致使的兼容問題,而瀏覽器差別偏向描述因爲不一樣瀏覽器廠商致使的兼容問題。

相比硬件設備來講,操做系統也給移動開發帶來了很多麻煩,在前面視覺篇的最後已經提到一個字體兼容的問題,參見:@元彥 給出瞭解決方案 《字體設置最佳實踐》。

另一個比較經典的問題,在Android下orientationchange事件回調,須要延遲一點時間觸發回調函數,才能獲取到正確的window.innerWidthwindow.innerHeight的值,在iOS是不須要作這個延遲的。分別使用iOS與Andorid設備訪問 DEMO,橫豎屏查看對比結果。

我通常會將Android設備的回調延遲300ms處理,代碼以下:

var isAndroid =  /android/.test(window.navigator.userAgent.toLowerCase());
function createOrientationChangeProxy(fn) {
    return function() {
        clearTimeout(fn.orientationChangeTimer);
        var args = Array.prototype.slice.call(arguments, 0);
        fn.orientationChangeTimer = setTimeout(function() {
            var ori = window.orientation;
            if (ori != fn.lastOrientation) {
                fn.apply(null, args);
            }
            fn.lastOrientation = ori;
        }, isAndroid ? 300 : 0);
    };
}
window.addEventListener('orientationchange', createOrientationChangeProxy(function() {
    if (window.orientation == 0 || window.orientation == 180) {
        resizeIcon();
    }
}), false);

但其實,即便延遲300ms也不能解決全部Android設備的問題,好比我在小米2原生瀏覽器上須要延遲800ms才能獲取到正確高寬。我想這與小米瀏覽器的內部實現有關,一些瀏覽器在進入全屏狀態收起地址欄時,會執行一個收起地址欄動畫,這個動畫大概要消耗500ms左右的時間,這個動畫並非全部瀏覽器都是這麼實現的,因此,我想多是由於這個緣由致使有些瀏覽器須要更長時間才能獲取到正確的高寬,也多是我猜錯了。

另外,我還在三星手機上遇到過一些更奇葩的問題,使用JavaScript處理animation動畫時,設置動畫屬性。好比:transformanimation時,必須使用-webkit前綴的屬性,若是沒有這個前綴,在三星手機原生瀏覽器下,動畫會失效,而在其餘瀏覽器下使用前綴的屬性是OK的。

操做系統差別與瀏覽器差別,沒有一個完整的邊界,產生的問題也模擬兩可。若是在全部Android設備上都出相同的問題,這樣的問題均可以認爲是操做系統差別,通常這類問題都是因爲Webkit內核或系統底層的一些緣由致使。

瀏覽器差別

對於移動Web開發來講,咱們處理的70%兼容問題都會是瀏覽器差別致使,在這裏我不會總結瀏覽器差別的兼容問題,由於實在太多,閱讀過 @jtyjty99999 mobileTech項目 就能體會到,那個篇幅,那個長度,簡直無力吐槽。能夠這麼說,只要瀏覽器版本在更新,就會不斷有新的兼容問題產生,一切瀏覽器個性化功能和對底層引擎的優化都是兼容問題的罪惡之源。

可是,要確定一點,移動開發兼容通常只須要作兩種瀏覽器的兼容:Webkit內核與IE的Trident內核。若是不考慮WP用戶的話,更是連IE兼容均可以省了,因此寫代碼時,都優先考慮-webkit前綴的兼容,這點是移動Web開發的優點。

瀏覽器的個性化

在iOS中,蘋果強制全部瀏覽器必須使用自家的Webkit內核,因此全部瀏覽器的體驗很是一致,出問題的話也都出同樣的問題,改問題也比較容易點。幸運的是iOS把它優化得十分不錯,因此更多的程序員都喜歡作iOS下的前端開發。

相比iOS,Andorid可謂是百花齊放,各個瀏覽器都個性十足,好比UC瀏覽器,它包含不少功能:

  • 極速模式
  • 自帶手勢,好比:左右手勢滑動切換頁籤
  • 無圖模式
  • 雲加速
  • 網頁預讀
  • 廣告過濾
  • 夜間模式
  • 等等

每一個瀏覽器優化的功能都是一個陷阱,均可能致使應用沒法正常工做。最多見的是瀏覽器自帶的手勢與頁面手勢衝突,致使頁面手勢沒法正常工做,又或者瀏覽自帶一些懸浮按鈕對頁面上的按鈕產生了遮擋等等。

一些不太容易碰見的異常就可能與應用場景有關。好比我以前作的一個功能,在頁面初始化時須要使用JS記錄頁面運行一些狀態參數,因爲UC瀏覽器的網頁預讀功能,它會自動識別當前頁面的下一頁按鈕,而後預讀下一頁而且提早渲染與處理JavaScript。這就致使頁面狀態記錄錯亂,由於在用戶沒有真實看到下一頁時,實際上狀態參數已經改變爲下一頁的狀態了。這個問題最後是在下一頁按鈕上加上了disabled樣式解決的,若是<a>disabled樣式或屬性,那麼UC在預讀時就會忽略掉。

再好比 APP下載連接被看成廣告過濾掉等等,相似這樣的問題還有不少,都是由於瀏覽器自身特性致使的兼容問題。

瀏覽器實現差別

瀏覽器差別除自身功能特性以外,還有不少實現差別致使的兼容問題,這樣的問題是最坑爹的。爲何說坑爹呢?看下面幾個例子:

軟鍵盤

文本框

  • 在一些Android瀏覽器下,文本框focus被激活時,層級最高,會擋住全部頁面元素(包括fixed元素);
  • 這種遮擋問題一樣在Android一些瀏覽器的<video>標籤中也有體驗,好比UC或QQ;

position:fixed

前些天又總結了一篇博文《微信內置瀏覽器WebApp開發,踩坑》也是有關瀏覽器踩坑的問題。

這些在正常狀況下,都認爲沒有問題的地方,每每都會出現各類奇葩的兼容問題,而正是這些問題耗費了咱們大量的精力和時間。

小結

如今回過頭看之前遇到的一些兼容問題,隨着Android版本、Webkit引擎和各類瀏覽器的升級,不少兼容都在從底層被解決,而且對標準的支持也愈來愈好。

之前我總是會糾結是否須要去解決一些老舊設備遇到的兼容問題,通過這麼長時間,對這個問題我也找到了一個本身的答案:「應該大膽的使用更高級,能帶給用戶更好體驗的特性,不要顧慮太多,移動技術發展得太快,快到等你作完這些兼容以後,這些設備已經被淘汰了。

和你們分享一組內部的統計數據:採樣12萬個,Android系統,Andorid 2.x 佔15.47%,Android 4+ 佔82.12%。

更正

視覺篇中提到的:維基百科中List of displays by pixel density詳細的記錄了各種設備的尺寸和分辨率。更正:維基百科頁面被刪除,緣由不明。使用兩個替代方案查詢設備的尺寸和分辨率:

相關文章
相關標籤/搜索