小程序與傳統HTML5的區別
小程序開放公測,互聯網圈內開始了各種解讀和猜測。其中有觀點認為小程序和HTML5有著緊密關聯,甚至小程序就是基于HTML5開發。
經過仔細研究文檔和代碼開發,從視圖層的角度來說,小程序與傳統HTML5還是有明顯的區別,主要區別在于:
1、開發工具不同;
區別于H5的開發工具+瀏覽器Device Mode預覽的模式,小程序的開發基于自己的開發者工具,可以實現同步本地文件+開發調試+編譯+預覽+上傳+發布等一整套流程。
2、開發語言不同;
小程序自己開發了一套WXML標簽語言和WXSS樣式語言,并非直接使用標準的HTML5+CSS3。
3、組件封裝不同;
小程序獨立出來了很多原生APP的組件,在HTML5需要模擬才能實現的功能,小程序里可以直接調用組件。
小程序開發者工具
微信小程序的開發工具,基于MINA框架(現已取消該名稱),現在官方公布的工具名為微信web開發者工具。小程序開發工具是一種基于Native System系統層的框架,由于并非運行在瀏覽器中,所以JavaScript在web中的一些諸如Document、Window等方法無法使用。
從執行的速度方面,普通HTML5和小程序有哪些不同呢,用一張圖表簡單表示下:
傳統HTML5在加載的時候受限于網絡環境,需要順序加載HTML、CSS、JS,然后返回數據,最后渲染頁面顯示在瀏覽器中。用戶經常需要等待很長時間,體驗會受到影響。
相比之下,小程序的兩個線程:Appservice Thread和View Thread會同時進行、并行加載,甚至Appservice Thread會更早執行,當視圖線程加載完,通知Appservice,Appservice 會把準備好的數據用setData的方法返回給視圖線程。
小程序的這種優化策略,可以減少用戶的等待時間、加快小程序的響應速度。
WXML
1、標簽
WXML在語法上更接近XML語言,遵循SGML規范,區別于HTML語言隨意的標簽閉合方式,WXML語言必須包括開始標簽和結束標簽,以image標簽為例,以下2種寫法都支持:
or
這里需要注意的是:
所有組件與屬性都是小寫,以連字符-連接。
2、文件引入
WXML提供兩種文件引入方式,import和include。區別在于:import可以引入定義好的template模板,模板是有作用域的;而include就是拷貝一個公用的代碼片段到目標文件中,適合做公共頁面片的拆分。
文件引入在小程序做模塊化拆分的過程中非常重要。
WXSS
1、尺寸單位
WXSS支持的單位有px、rem和rpx,其中rem和rpx可以針對屏幕容器進行適配,px則為固定尺寸。 其中1rpx=0.5px,在WXSS和WXML中定義的rpx單位最終會轉換為在手機端可以識別的rem單位。
建議:開發微信小程序時設計師可以用 iPhone6 作為視覺稿的標準。
所以工程師拿到750的設計稿,在PS中量取的容器大小,可以直接定義為rpx,不需要進行2倍尺寸的換算。
view{
font-size:26rpx;
width:400rpx;
height:400rpx;
}
備注:rpx的單位不光在樣式中會自適應,寫在WXML的style里也會根據屏幕自適應。
2、樣式引入
看到很多文章說小程序不支持樣式的@import,其實官方公布的第一個正式開發者工具就已經支持了。
import "../../wxss/common.wxss";
3、選擇器
小程序支持的選擇器在官方公布的文檔中包括.class、#id、 element、element,element、::after(注意是雙冒號)、::before這6種選擇器。
經過測試,小程序對于:first-child、:last-child、.class-a .class-b{},甚至更多層級的嵌套都是支持的。 不過官方并不推薦級聯的這種寫法,因為考慮到后面切Native的擴展可能,會沒辦法支持級聯選擇。
所以保險起見,不建議.class-a .class-b{}這種級聯的寫法,以免后期工具過濾導致頁面錯亂。
組件
小程序在0.10.102800的版本中加入了 textarea,并即將廢棄操作反饋的系列組件。
我們簡單通過一個表格來對比下HTML5和小程序的組件標簽的區別;
下面一一來分析下:
1、view
div和view都是盒模型,默認display:block。 盒模型在布局過程中,一般推薦display:flex的寫法,配合justify-content:center;align-items:center;的定義實現盒模型在橫向和縱向的居中。
2、text
除了text文本節點以外的其他節點都無法長按選中。截止到0.10.102800的開發者工具text支持嵌套text,不過有class的text會被面板過濾,樣式不影響。
* 友情提示!
3、 icon
icon可以直接用微信組件默認的圖標,默認是iconfont格式的,從WeUI那邊沿襲過來的一種做法。 自定義的icon推薦svg sprite格式或者iconfont。
目前來看,市面上還沒有很好的自動合并單個svg為svg sprite的工具,需要手動拼圖。
4、input
input 的類型,有效值:text, number, idcard, digit, time, date 。 input不需要設置line-height或padding來縱向居中,默認placeholder的文字是居中的。 小程序把checkbox和radio都單獨做成了組件,默認的input只支持輸入文本。 上傳文件在小程序里需要調用chooseImage事件完成;
小程序CSS里的 :focus 不生效,需要修改placehoder的樣式,通過placeholder-class=”class”來定義。
.login .input-group input::-webkit-input-placeholder {
color: #c0c0c0;
}
.login .input-group input:focus::-webkit-input-placeholder {
color: transparent;
}
5、picker
picker默認支持普通、日期和時間三種選擇器。 picker通過bindchange事件來調取range中自定義的數據數據,并展示到頁面中,調用的是系統原生的select。
這里小程序廢棄了select組件,考慮到的是這個組件的交互不適合移動場景,最終用picker代替了。
{{area[index]}}
Page({
data: {
area: ['中國', '美國', '巴西', '日本'],
}
})
6、 navigator
navigator支持相對路徑和絕對路徑的跳轉,默認是打開新頁面,當前頁面打開需要加redirect;
navigator僅支持5級頁面的跳轉;
navigator不可跳轉到小程序外的鏈接地址;
登錄頁
在小程序開發工具里,默認打開新頁面,工具左上角有返回按鈕。加上redirect,當前頁打開,不出現返回按鈕。
7、image
小程序的image與HTML5的img最大的區別在于:小程序的image是按照background-image來實現的。 默認image的高寬是320*240。必須通過樣式定義去覆蓋這個默認高寬,auto在這里不生效。
(開發者說這樣設置的原因是:如果設置 auto ,頁面布局會因為圖片加載的過程有一個閃的現象(例如高度從 0 到 height ),所以要求一定要設置一個寬度和高度。)
最新的api支持獲取圖片的高寬。不過這里返回的高寬是px單位,不支持屏幕自適應;
圖片包括三種縮放模式scaleToFill、aspectFit、aspectFill和9種裁剪模式,三種縮放模式的實現原理對應如下:
scaleToFill{
background-size:100% 100%;//不保持縱橫比縮放圖片,使圖片的寬高完全拉伸至填滿 image 元素
}
aspectFit{
background-size:contain;//保持縱橫比縮放圖片,使圖片的長邊能完全顯示出來。也就是說,可以完整地將圖片顯示出來。
}
aspectFill{
background-size:cover;//保持縱橫比縮放圖片,只保證圖片的短邊能完全顯示出來。也就是說,圖片通常只在水平或垂直方向是完整的,另一個方向將會發生截取。
}
8、button
額外補充下button的實現方式,button的邊框是用:after方式實現的,用戶如果在button上定義邊框會出現兩條線,需用:after的方式去覆蓋默認值。不過這個應該會在最近的開發者工具中修復。
button::after {
content:" ";
width:200%;
height:200%;
border:1px solid rgba(0, 0, 0, 0.2);
}
小程序不支持button:active這種樣式的寫法,button的點擊態通過.button-hover{}的樣式覆蓋,也可修改hover-class為自定義的樣式名。
9、css3動畫
最新版的開發工具已經支持transition和keyframes動畫,不用js苦哈哈的寫動畫隊列了。
除了官方公布的小程序的組件之外,有一些標簽比如,span、em、strong、b也是支持的,只是官方并不推薦使用。
瀏覽器內核
在iOS平臺上,微信的瀏覽器渲染內核是wkwebview;
而在Android平臺上,微信則采用了騰訊QQ瀏覽器2016年4月份發布的X5內核(blink內核)作為渲染引擎。
在小程序的開發工具上,小程序的JavaScript是運行在chrome內核(nwjs)中。
autoprefixer
小程序會在接下來的版本中加入自動補全css前綴,使用的插件是postcss的autoprefixer,設置的兼容級別是> ios 8及> android 4.1。
const browserOptions = {
browsers: [
'last 3 versions',
'ios >= 8',
'android >= 4.1',
]
}
也就是說,我們在寫css的時候只需要寫沒有前綴的寫法。比如:display:flex,工具自動編譯為display:flex;display:-webkit-flex。
1、flex布局
以文章列表為例,文章的形態包括純文字的和圖文混合的。圖文混合的文字不管是1行還是2行都需要相對于圖片縱向居中。用flex的布局,就可以實現這3種狀態不修改CSS文件,只按需隱藏DOM結構就搞定。
.media {
display: flex;
justify-content:center;//設置或檢索彈性盒子元素在主軸(橫軸)方向上的對齊方式。
align-items:center;//定義flex子項在flex容器的當前行的側軸(縱軸)方向上的對齊方式。
}
.media .content {
flex: 1;
}
在做傳統H5的時候,為了兼容各種低端設備的機型,通常不太敢輕易嘗試flex,但在小程序里就可以大膽的使用了。
2、智能裁圖
正是由于小程序把圖片處理成背景圖片,OM的素材管理頁面圖片的實現方式在這里遇到了一個挑戰。 簡單列舉下om各種不同尺寸圖片在平臺上的展示方案。
1、高<50px:
(1)寬<175px,原圖居中顯示;
(2)寬>175px,定寬等比上下居中顯示;
2、50px<高<400px:
(1)寬<175px,原圖居中顯示;
(2)寬>175px,定寬等比顯示;
3、高>400px:
(1)寬<175px,原圖居中顯示、超出400px高度隱藏;
(2)寬>175px,定寬等比顯示、超出400px高度隱藏;
這種方案,用css和img實現起來,只需要設置外層盒子最大高寬,圖片自適應縮放即可。
.pic-list .pic-item .pic-body .pic {
width: 100%;
text-align: center;
overflow: hidden;
max-height: 4rem;
min-height: 0.5rem;
display: -webkit-box;
-webkit-box-orient: horizontal;
-webkit-box-align: center;
-webkit-box-pack: center;
}
.pic img {
-webkit-box-flex: 1;
}
然而因為小程序里是用背景圖片的方式,簡單的css設置并不能實現智能裁圖的方案。需要配合js計算出不同尺寸圖片對應的適配尺寸。
.pic-list .pic-item .pic-body .pic {
width: 100%;
text-align: center;
overflow: hidden;
max-height: 800rpx;
min-height: 100rpx;
display:flex;
align-items:center;
justify-content:center;
}
這里需要后臺接口提供數據列表的圖片高寬,js對拿到圖片的不同尺寸進行算法計算,重新賦值再返回給數據。
3、css3動畫改變默認loading
小程序默認提供的loading是普通的菊花loading,這里OM使用自定義的keyframes序列幀動畫。
.icon-loading {
animation: loadingWhite 1.2s infinite linear;
animation-timing-function: steps(10);
}
@keyframes loadingWhite {
0% {
background-position:0 0;
}
100%{
background-position:-500rpx 0;
}
}
寫在最后
微信小程序集成了很多原生APP的組件,從體驗和頁面流暢度來說,都會比HTML5要優秀很多。
微信小程序相對于HTML5開發來說,除了熟悉API需要學習成本之外,開發難度指數3顆星,還是很容易上手的。
開發者工具、組件和API目前剛剛對外公測,還不算太成熟,里面還有很多坑需要開發者去填。
文章篇幅有限,在這里只能簡單從UI開發角度介紹下小程序的開發經驗。有關小程序的更多API,可以查閱小程序開發文檔 。
由于開發工具一直在持續更新,文章中可能會有不準確或者更新不及時的地方,還請諒解。