從移動平臺崛起以來,HTML5移動應用開發迅速變成了熱門話題,開發者們被各種開發HTML5移動應用的方法搞得暈頭轉向,今天請到了金山云基礎架構部研發負責人柴春燕給大家分享如何避免HTML5移動應用最容易踩的那些坑。
柴春燕--
微軟社區精英計劃博客組負責人,HTML5研究小組成員,擅長HTML5及移動應用開發;
具有多年Web開發經驗,曾參與開發微軟Visual Studio 2010中文學習平臺,基于SaaS模式的E-Learning系統;
曾負責當當網Web前端開發及移動應用開發,擔任百度音樂高級研發工程師;
目前就職于金山云,初期負責金山云前端架構,現任基礎架構部研發經理。
01/移動應用中HTML5的新特性
工欲善其事,必先利其器。我比較推崇的學習技術的方式,是先整體了解,然后結合實際需求,再做針對性的學習。整體了解的方式,比較建議是直接看官網的API文檔,這里可以推薦幾個網站: http://www.w3school.com.cn/html5/index.asp, https://developer.mozilla.org/zh-CN/docs/Web/Guide/HTML/HTML5, http://www.html5rocks.com, http://caniuse.com/
其中,特別說明下http://caniuse.com/,通過這個網站,我們可以非常快速的查詢到你所想使用的html5的特性在各個瀏覽器,包括不同終端的瀏覽器的兼容性情況。
HTML5 在移動應用開發上面能夠利用的特性主要有:
1. form input type
表單是我們在開發中經常會遇到的,如果按照傳統的方式,要介入jquery validate或者自己寫正則進行判斷,但是其實html5的form表單新增的input type屬性,能夠快速幫我們實現所需要的功能。
2. video & audio
移動瀏覽器是不支持flash的,在一些微信專題活動中,經常會看到嵌入音頻,那么audio標簽就是比較適合的應用場景,html5中audio提供的api attr還是比較全面的。
視頻格式一般有mp4和webm兩種格式,在使用的時候,一般建議同時生成兩種,根據瀏覽器兼容性,進行相應的選擇。音頻audio,一般會同時制作mp3 ogg格式。
3. storage
關于web storage,大家可以參考我之前分享的一篇內容:
http://www.chaichunyan.com/topics/html5-training/5.html5_storage/#/
重點是localstorage,尤其是我們在做移動應用的性能優化時,localstorage能夠發揮很大的作用。
學習的時候,建議大家帶著問題去學習,比方說“localstorage最大的存儲容量是多少?”“有沒有有效期?”“cookie是有域的概念的,那么localstorage呢?”
4. css3
html5其實更多的是一個web標準,這個標準里邊,包含了html、JavaScript api、css。css3是我們在移動應用中要重點學習和掌握的。
1.選擇器
2.自定義字體
3.多欄布局
4.文字,容器陰影
5.圓角
6.漸變效果
7.動畫 ...
大家可以通過下面一個例子有一個直觀的印象:
http://www.chaichunyan.com/topics/html5-training/7.css3_summary/demos/index.html
之前很多我們需要通過js或者切圖實現的效果,在移動端,就可以直接通過css3實現。
這里特別強調下關于布局,css3彈性布局,希望大家能夠仔細去了解,我在面試時候,必問的一道題,當然,面試只是手段,更重要的是希望能夠學以致用,真正在實際工作中發揮作用。
flexbox布局的兼容性,彈性盒模型實現的原理,這些我們在做移動終端調試時候,如果只是靠反復試錯,那么效率是非常低的。
了解了html5的特性,開發者就會在移動應用上一展身手了。
02/HTML5移動應用中踩過的那些坑
1.布局
移動瀏覽器訪問的web站點,后面稱為mobile webapp哈(泛指移動終端瀏覽器訪問的web站點),能不能使用傳統的流式布局?答案是可以,但是要慎用。
mobile webapp對css3的彈性布局支持還是比較給力的,iOS Safari還好,但是Android的碎片化非常嚴重,尤其是Android上面各種第三方瀏覽器會做各種各樣的定制化,使用flexbox比float能夠減少你在布局調試上的時間,而且兼容性有保證。
2.圖片適配
這里邊要提供一個概念,是屏幕分辨率和物理分辨率,為什么我們使用ios看到的圖片清晰度那么高,原因是普通的手機屏幕,一點顯示一個像素,但是iphone4s 以后是一個點四個像素。
那按照320的設計稿切出來的圖片,在iphone上面顯示肯定是有鋸齒的。
處理方法可以參見我之前分享的一篇文章:圖片的適配與清晰度
http://blog.csdn.net/spring21st/article/details/7513906
3.字體
我把字體的處理分為兩類,一種是藝術字體、icon,另一種是我們在頁面中的字體。
移動終端對網絡的要求是比較高的,我們要盡可能減少網絡請求,圖片是非常大的網絡開銷,當然,我們可以用合并圖片的方式減少請求數,但是請求量變大了。
css3支持web fonts,所以,我們可以引入字體文件,而不是所有的字體都是通過切圖的方式來實現。對于icon,一種方式是base64處理,但是現在更常見的做法,是轉換成矢量字體。
這里推薦一個網站:font awesome http://fortawesome.github.io/Font-Awesome/icon/css3/
這里邊涵蓋了大部分我們會用到的圖標,當然,公司有精力和人力的情況下,建議可以維護自己的矢量字體庫。
4.橫豎屏
我們可以通過css 的media query 判斷橫豎屏。
但是這種只能控制樣式展現,當我們需要監聽橫豎屏變化的時候,就只能通過js監聽window.onorientationchange事件的方式實現。
但是,下面這種情況會讓你很無語:
那我們推薦下面這種實現方案:
相比較pc web,mobile webapp的調試更復雜,而且未知的問題更多,遇到問題,我們要有耐心去跟蹤定位,就像之前我們遇到iscroll性能問題、fast-click穿透的問題,都是一點一點排查處理的。
03/混合應用(Hybrid)的注意事項
現在“快速迭代,敏捷開發,低成本上線“基本上是每家公司都追求的目標,混合應用就是在這種場景下應運而生。
Hybrid App優點眾多,Web前端工程師0成本介入,不依賴版本的實時更新,快速實現跨平臺需求,等等。但是,我對混合的看法是,根據實際情況合理使用,因地制宜。
那么什么樣的場景適合混合應用開發?
1. 快速原型,驗證產品功能。我們之前開發過一個app,Android和iOS提供宿主環境,webview展現內容都是通過html5實現的,半個月就開發上線了,較之傳統應用開發人員成本和時間成本都縮短很多。
2. 內容類的應用,比如csdn的app,就是采用hbuilder混合方案實現的,對性能要求沒有那么高。
在考慮hybird的時候,要避免以下幾個誤區:
(1)為了HTML 5而Hybrid App
html5只是技術實現手段而已,要根據公司的實際業務場景,以及人員配比,綜合考慮,不能因為react native比較火,就必須要在公司推行這種實現方案,我覺得為技術而技術是不可取的。
(2)忽略移動應用中的關鍵因素
mobile webapp本質上還是基于PC的一種開發模式,開發者使用PC瀏覽器模擬App中的webview進行調試。PC瀏覽器與手機webview的區別是巨大的,包括能支配的CPU資源,最大占有的內存,運行的網絡環境,click和touch事件的區別,瀏覽器對CSS/JS的解析和對事件處理等等。
app工程師考慮比較多的內存的問題,這些在web開發時候是很少考慮的。另外,就是網絡環境方面,雖然現在3g、4g覆蓋率越來越高,但是移動終端的訪問和pc還是有很大差距,wifi和蜂窩網絡的切換,基站變化等諸多因素都會導致網絡間歇性斷開,web開發對于這種不穩定網絡環境問題的處理上都有所欠缺。
(3)交互體驗一致性
ios和Android的交互設計是兩套規范,雖然有相似的地方,但是從操作習慣上,就已經決定了,我們想用一套交互設計,適配兩個平臺是很難的,包括包括視覺風格,界面切換,操作習慣等。
Hybrid App方案是一把雙刃劍,一方面它平衡了Native App和Web頁面的優缺點,一定程度上解決了Native App開發過程中迭代慢,版本依賴,Native開發資源不足的問題,但另一個方面過度依賴Hybrid方案會造成Web前端開發成本快速上升,甚至造成App整體體驗下降,甚至造成功能缺失。
回到最開始那句話”不要為了Hybrid而Hybrid“,根據實際場景,控制好方案中native和web的邊界。
04/Q&A
Q1:關于響應式開發中對于手機屏幕高度的解決有沒有什么好的解決方案?
響應式開發本質上是移動設計優先的一種開發方式,我沒太明白對于手機屏幕高度的解決,具體的問題是什么樣的,原則上高度是不需要做處理的,除非是你對首屏有要求。關于響應式開發,可以看看我這篇文章http://www.chaichunyan.com/index.php/2016/03/03/html5-wrd/
Q2:對首屏有要求的情況, 除了判斷高度還有沒有其他好的解決方案?如果是flex布局可以解決這個問題嗎?
問題的根本是獲取首屏的高度,(1)如果你是后端渲染的話,可以獲取機型和瀏覽器版本,拿到屏幕分辨率做適配 (2)根據屏幕寬度做適配,但是做不到完全絕對的首屏自適應,如果有更好的方案,我再跟大家分享。
Q3:hybrid開發中,h5頁面太多的話,會不會影響ios發布?
之前有ios對phonegap這種跨平臺的應用審核是不通過,不過現在放開這個限制了。h5頁面過多,會影響應用的性能和體驗,建議可以把h5打包放到ipk里邊,但是要做好靜態資源的版本管理。
Q4:css3 彈性布局中, 由于android碎片化嚴重的問題, 能不能有好的案例指導? 我們要求支持到android4以上版本。
真的要善用文檔和工具, http://caniuse.com/#search=flex, 我分享時候提到的這個網站,明確說明了flex兼容性。
如果是Android4.4以上機型,基本上可以放心使用,注意的地方有兩個:1. 要記得寫各個瀏覽器的css前綴 2. flex里邊可以嵌套flex.
Q5:hybird開發過程中, 原生代碼登錄權限問題,h5部分的頁面,如何共享登錄相關信息?
這要看你實現的方案,(1)嵌套靜態的h5頁面,那么需要native打開webview的時候,使用js briage調用頁面js的方法,寫入用戶信息,實現登錄共享 (2)如果打開的是動態渲染的頁面(如php輸出的頁面),那么可以在請求的url中攜帶用戶token,php通過query string判斷驗證,這個是native和webview數據交互的問題。
Q6:h5動畫在部分安卓webview中有時候會出現卡頓,這種情況改怎么優化呢?
1. 可以做簡單的測試,看看瀏覽器支持的情況,如果瀏覽器支持不夠好,那么可能要做降級處理。
2. 減少動畫效果,因為動畫是要使用gpu渲染的,原生app能夠流暢,很大程度上是直接調用硬件處理的。
優化的方案我這邊基本上是降級處理,Android低版本不支持的話,就使用基本動畫,比方不會使用3D翻轉。因為h5畢竟受限于webview環境,像jquery 和 zepto都提供對機型和瀏覽器的判斷。
Q7:在移動端瀏覽器上能支持h5離線存儲的性能嗎?
No problem.我們在實際項目中,優化前端性能,曾經用localstorage做靜態資源的版本管理和存儲。
更多技術干貨關注公眾號“極牛”。
前面學習了HTML5的基礎新元素,接下來小編將繼續分享HTML5必學的知識點--HTML5新表單
在開始之前,先來了解一下HTML5的聲明,<!doctype html>,通過HTML的聲明,體現W3C故意弱化HTML的版本,但是小標要說明下版本不更新,不等于內容不更新,而是W3C希望HTML5是融合版本。
關于HTML的發展歷史, HTML的規范不嚴格一直以來就是前端開發人員頭疼的地方, 元素定義大小寫不敏感。
直到XHTML 1.0的出現 - 前端開發人員擁抱,因為此時的HTML只允許小寫
XHTML 2.0版本出現后 - 前端開發人員重新回到HTML, 推翻了之前很多習慣
HTML 4版本出現之后 - 比較好的版本
HTML 5版本出現 - 經歷8年后,終于在2014年10月底發布
HTML5的特點:移動端瀏覽器相比PC端瀏覽器對H5的支持更好,這要感謝蘋果公司 - 喬布斯
小編提醒大家:目前網上所謂的H5,并不是指現在所學HTML5技術,HTML5的新特性內容不多,與JS(難)配合使用
那么實際工作中使用多不多?其實實際上來說,相對并不多
其實就是在為將來學習 - HTML5將來一定是主流。
*******華麗分割線*******
接下來開始學習,HTML5必學知識點—新表單,主要從4個方面入手:新類型、新元素、新屬性、新驗證
1.email類型 - 判斷字符串中是否包含"@"符號,注意的是不能以"@"開始、不能以"@"結束
2.搜索類型 - search
3.URL類型 - 判斷字符串中是否包含"http:",注意的是以"http:"開始,驗證通過,以"http:"結束,驗證通過
4.電話號碼類型 - tel,注意的是只有在手機端瀏覽器訪問時有效果
5.數字類型 - number,需要注意的是允許輸入非數字內容,但是不允許提交,在設置min和max時,允許輸入范圍外的值,不允許提交;這個類型有一些屬性: min - 設置數字的最小值;max - 設置數字的最大值;step - 設置步長,每次增加或減小的量值
6.范圍類型 - range,效果就是滑動條,屬性:min - 最小值、max - 最大值、step - 步長、value - 當前值
7.顏色類型 - color
8.日期類型 - date,日期格式 - yyyy/MM/dd
9周、月份類型 (實際很少使用)
10周 - week(實際很少使用)
11月份 - month(實際很少使用)
1.<datalist>元素,用法:需要配合input元素使用,在input元素中定義list屬性(值為datalist元素的id值),好處就是數據與結構的分離
2.<progress>元素,就是實現一個進度條,屬性有:max - 設置進度條的最大值、value - 設置進度條當前的值
3. <meter>元素,用法和<progress>元素類似,作用 - 刻度,屬性包括:min和max - 設置最小值和最大值、 value - 表示當前值,high和low - 設置預警值(舉個常見的例子,當你手機的電量小于10%時候,一般會顯示紅色的一小段進度)
4.<output>元素,和<input> 輸入框正好相反,<output>是輸出框,屬性:for指定要輸出的元素進行關聯(實際開發中,很少使用)
1.placeholder屬性:就是實現input輸入框的默認提示信息,相比value屬性值更好用。這個在實際開發過程中非常常見
2.autofocus屬性:就是自動獲取焦點、用法有點不同,它不是key=vlaue的形式,而是直接只定義屬性名(沒有屬性值)
3.multiple屬性:就是允許輸入框輸入多個值,用法和autofocus一樣只定義屬性名(沒有屬性值)
4.form屬性(實際開發中用到不多):就是表單元素定義在表單之外,用法 - 值是相關表單的id屬性值
1.驗證屬性:
required屬性即:驗證是否為空?返回false,表示當前元素值為空, 返回true,表示當前元素值不為空
pattern屬性即:驗證正則表達式,定義正則表達式時,不能添加"http://", 正則表達式不能驗證是否為空
min和max屬性即:驗證最小值和最大值 ,只和number類型的input元素配置使用
minlength和maxlength屬性即:驗證最小長度和最大長度,minlength - 驗證最小長度,maxlength - 限制最大長度(輸入內容的長度不能大于maxlength的值)
validity屬性即:HTML5提供表單驗證的接口,通過該屬性得到validityState對象,該對象提供一系列的有效狀態, 有效狀態可用于表單驗證,得到validatyState對象,elem.validaty - 得到該對象
2.有效狀態
valid - 返回Boolean,表示驗證是否通過,true - 表示驗證通過, false - 表示驗證失敗,
valueMissing - 表示值是否為空,返回值true - 表示元素值為空(錯誤)、false - 表示元素值不為空(正確) 注意該狀態配合required屬性使用
typeMismatch - 表示元素類型是否匹配,返回值true - 表示元素類型不匹配、false - 表示元素類型匹配、 該狀態配合email、url、number等使用
patternMismatch - 表示正則表達式是否匹配、返回值true - 表示正則表達式不匹配、false - 表示正則表達式匹配,該狀態配合pattern屬性使用
tooLong - 表示元素內容長度是否過長,返回值true - 表示元素內容長度過長,false - 表示元素內容長度不長,該狀態配合maxlength屬性使用
maxlength屬性 - 限制屬性,tooLong可能不會出現(完整性)
rangeUnderflow - 表示元素值是否小于min值,返回值true - 表示元素值小于min的值,false - 表示元素值不小于min的值 該狀態配合min屬性使用
stepMismatch - 表示元素值與step值是否不符,返回值true - 表示元素值與step值不符,false - 表示元素值與step值相符 該狀態配合step屬性使用
customError - 自定義錯誤,配合setCustomValidity()方法使用,作用就是替換之前的判斷表達式,自定義錯誤提示信息setCustomValidity(自定義錯誤信息),一旦調用該方法,默認認為就是錯的,上述所有的有效狀態返回錯誤值 驗證正確時,調用該方法,將錯誤信息置為空
Type=“email” 限制用戶必須輸入email類型Type=“url” 限制用戶必須輸入url類型,“http://”Type=“range” 產生一個滑動條表單Type=“number” 產生一個數字意義表單Type=“search” 產生一個搜索意義的表單Type=“color” 生成一個顏色選擇的表單Type=“time” 限制用戶必須輸入時間類型Type=“month” 限制用戶必須輸入月類型Type=“week” 限制用戶必須輸入周類型Type=“datetime-local” 選取本地時間Type=”date” 限制用戶必須輸入日類型
<form action="" oninput="x.value=parseInt(a.value)+parseInt(b.value)">
<input id="a" type="range" min="0" max="100">100+
<input id="b" type="text" value="50">=
<output name="x" for="a b"></output>
</form>
<input type="url" list="url_list" name="link" />
<datalist id="url_list">
<option label="W3School" value="http://www.W3School.com.cn" />
<option label="Google" value="http://www.google.com" />
<option label="Microsoft" value="http://www.microsoft.com" />
</datalist>
required 監測是否為空。min 最小max 最大step 步幅 確定一個法定值。0 3 6 9 (不能寫負值)list 必須結合datalist標簽,綁定datalist id名稱。 autocomplete 是否自動提示信息 屬性值 on 打開 ;off 關閉 (是否有緩存)注:默認值是on ;
placeholder 文本框的提示信息 autofocus 自動聚焦。一個頁面只能由一個。pattern 后面的屬性值是一個正則表達式。(js)novalidate 取消驗證multiple 選擇(上傳)多個
*請認真填寫需求信息,我們會在24小時內與您取得聯系。