移動客戶端的開發類型(站在前端立場上來講),主要是三種:
Native App(原生APP),也就是徹底使用移動設備系統語言寫的客戶端,iPhone iPad就是純Object-C,安卓就是純JAVA, 是性能最棒的開發方式,但靈活性很差。
Web App, 就是在移動瀏覽器裏打開的,純HTML+CSS+JS,說白了就是個網頁,只不過很是的富應用,好比手機瀏覽器訪問的GMAIL。就是在瀏覽器裏打開的頁面。IOS支持能夠在桌面建立訪問的快捷方式,可是說到底仍是打開Safari跑。並且對設備硬件的接口什麼的挺薄弱。
Hybrid App.[HTML5 in mobile devices] 。其實是使用原生寫了一個容器,而後使用HTML+CSS+JS來實現用戶界面和交互。Web App的短處即可以克服(由於本身寫的容器能夠輔助暴露偏底層的接口,好比本地存儲或者麥克風控制之類),同時比起純原生的java或者object-c開發靈活性要高(更新能夠更快更迅速,也不依賴於市場,由於說白了,就是本身下載更新網頁資源。)實際上這種方式已經不限於移動端。豌豆莢實際上是個pc端的hybrid app。javascript
就目前來講,咱們只須要考慮webkit內核的瀏覽器和chrome,uc,qq,小米手機瀏覽器就行了。移動端更新換代比pc快多了,兼容性問題會愈來愈少。但移動設備的尺寸不一樣,移動端須要作大量的適配工做。css
衆所周知,手機屏幕分辨率是手機的重要參數之一。
你們都知道移動端設備屏幕尺寸很是多,碎片化嚴重。尤爲是Android,你會聽到不少種分辨率:480×800, 480×854, 540×960, 720×1280, 1080×1920,並且還有傳說中的2K屏、4K、5k等。近年來iPhone的碎片化也加重了:640×960, 640×1136, 750×1334, 1242×2208。html
俗話說物理分辨率是硬件所支持的,邏輯分辨率是軟件能夠達到的。前端
物理尺寸是指屏幕的實際大小。大的屏幕同時必需要配備高分辨率,也就是在這個尺寸下能夠顯示多少個像素,顯示的像素越多,能夠表現的餘地天然越大。而真正決定顯示效果的,是邏輯像素尺寸。java
咱們在viewport中,獲取到的,如"width-device",是邏輯像素。因此咱們的適配是針對邏輯像素尺寸的。jquery
dpi,表示的是每英寸所擁有的像素(pixel)數目,數值越高,即表明顯示屏可以以越高的密度顯示圖像。當達到人眼的極限分辨率時,喬幫主給它取了一個很高端的名字——Retina。ios
em單位是相對於父節點的font-size。CSS3新增了一個相對單位rem(root em,根em)。git
這個單位與em有什麼區別呢?區別在於使用rem爲元素設定字體大小時,仍然是相對大小,但相對的只是HTML根元素。這個單位可謂集相對大小和絕對大小的優勢於一身,經過它既能夠作到只修改根元素就成比例地調整全部字體大小,又能夠避免字體大小逐層複合的連鎖反應。目前,除了IE8及更早版本外,全部瀏覽器均已支持rem。對於不支持它的瀏覽器,應對方法也很簡單,就是多寫一個絕對單位的聲明。這些瀏覽器會忽略用rem設定的字體大小。github
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
meta標籤表示:強制讓文檔的寬度與設備的寬度保持1:1,而且文檔最大的寬度比例是1.0,且不容許用戶點擊屏幕放大瀏覽;web
媒體查詢還有不少參數,這裏再也不細述。
咱們採用rem進行移動端的適配。根據設計稿定高寬設計出來頁面,而後轉換爲rem單位。
@media only screen and (max-width: 320px), only screen and (max-device-width:320px) { html { font-size:10px; } } @media only screen and (max-width: 640px), only screen and (max-device-width:640px) { html { font-size:20px; } } .test-div{width: 10rem;}
那麼這個.test-div的寬度在320px的分辨率下會是10 * 10 = 100px, 在640下是10 * 20 = 200px,從而達到了彈性縮放的目的。
可是這樣作仍是有2個問題:
①隨着各類新手機的發佈,分辨率也碎片化了,咱們沒法預知未來會出現的分辨率寬度,咱們不可能把全部要兼容的分辨率寫到css裏。
②這樣寫只能作到頁面適配不一樣的寬度,對於那種在各類屏幕上都要在一屏幕內顯示的頁面,就沒有辦法適配了。
比較理想解決適配的問題就得靠js了,思路很是簡單,判斷一下當前終端的寬度和設計稿寬度的比例,計算出須要縮放的倍數,而後根據這個倍數值改變html的字體大小便可。
若是須要橫豎屏都適配,那麼根據終端寬高比例較小的那一個來計算。用通俗的語言來講,若是終端屏幕比設計稿更加寬矮一些,那麼久根據它和設計稿的高度比例來計算字體。插件代碼以下:
/* # 按照寬高比例設定html字體, width=device-width initial-scale=1版 # @pargam win 窗口window對象 # @pargam option{ designWidth: 設計稿寬度,必須 designHeight: 設計稿高度,不傳的話則比例按照寬度來計算,可選 designFontSize: 設計稿寬高下用於計算的字體大小,默認20,可選 callback: 字體計算以後的回調函數,可選 } # return Boolean; # xiaoweili@tencent.com # ps:請儘可能第一時間運行此js計算字體 */ (function ($, window) { var init = function(option){ var count = 0, designWidth = option.designWidth, designHeight = option.designHeight || 0, designFontSize = option.designFontSize || 20, callback = option.callback || null, root = document.documentElement, body = document.body, rootWidth, newSize, t, self; !function () { rootWidth = root.getBoundingClientRect().width; self = self ? self : arguments.callee; //若是此時屏幕寬度不許確,就嘗試再次獲取分辨率,只嘗試20次,不然使用win.innerWidth計算 if( rootWidth !== window.innerWidth && count < 20 ) { window.setTimeout(function () { count++; self(); }, 0); } else { newSize = getNewFontSize(designWidth,designHeight,designFontSize); //若是css已經兼容當前分辨率就無論了 if( newSize + 'px' !== getComputedStyle(root)['font-size'] ) { root.style.fontSize = newSize + "px"; return callback && callback(newSize); }; }; }(); orientchange(t); } //返回root元素字體計算結果 var getNewFontSize = function(designWidth,designHeight,designFontSize) { var scale = designHeight !== 0 ? Math.min(window.innerWidth / designWidth, window.innerHeight / designHeight) : window.innerWidth / designWidth; return parseInt( scale * 10000 * designFontSize ) / 10000; } //橫豎屏切換的時候改變fontSize,根據須要選擇使用 var orientchange =function(t) { window.addEventListener("onorientationchange" in window ? "orientationchange" : "resize", function() { clearTimeout(t); t = setTimeout(function () { self = self ? self : arguments.callee; }, 200); }, false); } var Mobileadapter = function(opt){ if (!opt) { throw("配置不可爲空"); } var settings = $.extend({ designWidth: 640, designHeight: 1136, designFontSize: 20, callback: function (argument) { console.timeEnd("test") } }, opt); init.call(this, settings); } $.initMobileadapter = Mobileadapter; }(jQuery, window));
使用:
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> <script type="text/javascript" src="mobileadp.js"></script> <script> $(function () { $.initMobileadapter({ designWidth: 650, designHeight: 1800, designFontSize: 20 }); }(jQuery, window)); </script>
幾點問題:
①這段代碼對viewport有要求,必須是width=device-width initial-scale=1,即窗口的大小是設備物理寬度(分辨率 / devicePixelRatio),而且禁止縮放。另外還有一種作法就是手機淘寶的作法,窗口大小是分辨率寬度,而後縮放倍數是1/devicePixelRatio,這裏暫且不討論。
②安卓上的問題。通過實測,有些安卓機器,使用1的viewport,在頁面剛加載的時候。不論是讀取window.innerWidth,仍是doc的getBoundingClientRect().width,或者是body的clientWidth,都不是設備的物理寬度。因此使用setTimeout,異步100ms執行獲取屏幕寬度的代碼就準確了。
由於width=device-width initial-scale=1,documentElement的寬度又是100%,因此當這兩個值相等的時候咱們能夠認爲目前獲取到的屏幕寬度是準確的。那麼使用此條件做爲判斷條件,不斷的setTimeout(fun(){}, 0)去判斷,當此條件爲真時改變documentElement的字體。能夠儘量快的執行目標代碼。可是又萬一這兩個值一直不相等又不能無限的死循環下去,因此設置了一個嘗試上限,到上限以後用窗口寬度來計算(縮放比例不對的話用戶起碼能夠看到完整的頁面)。在chrome下測試,執行40次代碼的平均時間是230ms,考慮到安卓機的js引擎速度,將上限設爲了20。
③建議將這段代碼放到head裏,第一時間計算好html的fontSize,避免重繪。若是你有有一些跟獲取dom元素尺寸相關的操做,就得放到這個計算函數的回調裏面了,這時候就不能放到head裏(由於運行的時候dom都還沒加載),只能放到底部或者doc的ready事件裏了。最佳實踐是有一個全屏的loading畫面,當fontSize計算好了以後再把真正的頁面展現出來。
以Chrome Emulation的Apple iPhone4爲基礎(最小屏幕)適配。
移動端設備的分辨率:iPhone設備分辨率寬度分別爲640、750、828,如今的設計稿通常是使用640、750的寬度。實際開發時須要將寬高減半,包括字體。那麼寬度爲640px的設計稿對應的designFontSize就是20px。
將px轉換爲rem的公式:&rem=$px /designFontSize * 1rem(&、$爲數字);
在css編寫中,咱們能夠經過函數計算出轉換後的rem。如在sass編寫rem轉換函數以下:
// pixels to rems $designFontSize: 20px !default; //640px psd @function pxToRem($px) { @return $px / $designFontSize * 1rem; }
在編寫css時直接量取psd設計稿的值,如:
.test-div{width: pxToRem(60px);}
因爲移動端的兼容性較好,儘可能使用HTML5+CSS3。尤爲CSS3。
CSS3,除了文字陰影(text-shadow)、盒子陰影(box-shadow)、圓角(border-radius)、背景漸變(background: linear-gradient(#000, #fff))、2D變換(transition)、動畫(animation)等你們耳熟能詳的經常使用屬性外,還有如-webkit-mask、-webkit-text-stroke、-webkit-nbsp-mode、-webkit-tap-highlight-color、-webkit-box-reflect、-webkit-marquee、-webkit-box等。其中-webkit-box能夠很好的佈局。
jQuery Mobile和Zepto是移動端的js庫。jQuery Mobile至關於PC端的jQuery UI,它提供了不少頁面的UI庫,可以很快的開發出漂亮的界面,適合公司沒有UI設計師的前端開發人員來進行移動端的開發。Zepto至關於PC端的jQuery,它提供了不少方法和功能,可以很快的實現各類需求和功能,適合公司有UI設計師的前端開發人員來進行移動端的開發。
jQuery Mobile的缺點,主要有兩點:一是重,二是UI限制太大。固然jQuery Mobile性能上沒有zepto好。
zepto.js是一個專爲mobile WebKit瀏覽器(如:Safari和Chrome)而開發的一個JavaScript框架。它標榜本身在其簡約的開發理念,可以幫助開發人員簡單、快速地完成開發交付任務。更重要的是這個JS框架,是超輕量級的,只有5KB。zepto.js的語法借鑑而且兼容jQuery。
若考慮移動端與WEB端的統一性選用jquery,單純從移動端來說zepto.js是首選。
能夠查看另一篇文章《全屏滾動-jQuery插件實現》。
使用預約義的動畫Animate.css
①檢測動畫結束事件:
$('#yourElement').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', doSomething);
②能夠更改動畫的持續時間,增長延遲或改變顯示次數:
#yourElement { -vendor-animation-duration: 3s; -vendor-animation-delay: 2s; -vendor-animation-iteration-count: infinite; }
注意:必定要在CSS恬當的的前綴(webkit, moz等)代替「vendor」。
③添加延遲動畫:
selector.delay(300).queue(function(){ //do something })
另外,可使用move.js實現自定義動畫。
-------------------------------------------------------------------------------------------------------------------------------------
完
轉載需註明轉載字樣,標註原做者和原博文地址。
更多閱讀:
http://ons.me/wp-content/uploads/2014/04/flexbox.html
http://www.superslide2.com/TouchSlide/
http://www.cnblogs.com/aimyfly/p/3843977.html
http://www.w3cplus.com/mobile/mobile-terminal-refactoring-mobile-layout.html