前段時間完成了公司一個產品的 HTML5 觸屏版,開發中使用了 Zepto 這個著名的 DOM 操作庫。
爲什麼不是 jQuery 呢?因爲 jQuery 的目標是兼容所有主流瀏覽器,這就意味着它的大量代碼對移動端的瀏覽器是無用或者低效的。
而 Zepto 只針對移動端瀏覽器編寫,因此體積更小、效率更高,更重要的是,它的 API 完全仿照 jQuery ,所以學習成本也很低。
但是在開發過程中,我發現 Zepto 還遠未成熟,其中包含了一些或大或小的“坑”,與 jQuery 的差距還是很明顯的,所以寫篇文章記錄下,希望對後來者有幫助
注意,本文撰寫時 Zepto 版本爲 1.0 正式版
從哪裏下載 Zepto
這個問題看起來很蠢,從官網下載不就行了嘛!可是你有沒有發現下載鏈接上面有行小字呢?
There are more modules; a list of all modules is available in the README.
在這個 README 裏面你會驚奇地發現,Zepto 源碼中有 14 個模塊,而官網提供的標準版裏面只有 7 個模塊!而且居然不包含對移動端開發非常重要的 touch 模塊(提供對觸摸事件的支持)!
所以我的建議是,不要從官網下載,而是從 Github 下載了源代碼之後自己 Build 一個版本,這樣你可以自行挑選適合的模塊。比如我挑選的模塊是這麼幾個:
polyfill,zepto,detect,event,ajax,form,fx 這7個就是標準版包含的模塊
fx_methods 有了這個模塊之後,.show() .hide() 等幾個方法才能支持動畫了,比如
.show('fast')
data 提供對 .data() 方法的完整支持,像 jQuery 一樣用內存對象存儲
assets 移除 img 元素後做一些特殊處理,用來清理內存
selector 更多的選擇器的支持,後面會提到
touch 對觸摸事件的支持,比如 tap 事件
如果你對 Node 不瞭解不知道如何 Build 的話,可以下載我的版本
不要用 click 事件,用 tap 代替
這個估計已經廣爲人知了,因爲 click 事件有 200~300 ms 的延遲,爲了更快的響應,最好用 Zepto 提供的 tap 事件
不相信的話,可以用以下代碼測試一下
var t1,t2;$('#id').tap(function () { t1 = Date.now(); });$('#id').click(function () { t2 = Date.now(); alert(t2 - t1); });
Zepto 對 CSS 選擇器的支持
鄭重提醒,:text :checkbox :first
等等在 jQuery 裏面很常用的選擇器,Zepto 不支持!
原因很簡單,jQuery 通過自己編寫的 sizzle 引擎來支持 CSS 選擇器,而 Zepto 是直接通過瀏覽器提供的 document.querySelectorAll
接口。
這個接口只支持標準的 CSS 選擇器,而上面提到的那些屬於 jQuery 選擇器擴展,所以仔細看看這個網頁,注意一下這些選擇器。
當然也有好消息,就是上面提到的 selector 模塊,如果有這個模塊的話,能夠支持 部分 的 jQuery 選擇器擴展,列舉如下:
:visible :hidden
:selected :checked
:parent
:first :last :eq
:contains :has
元素的尺寸計算
首先 Zepto 沒有 .innerHeight() .outerWidth() 等四個方法,其次,它的 .height()/.width() 方法也不完善,對於 display:none
的元素,計算出的高寬都是 0
而這在 jQuery 裏面是沒有問題的,因爲 jQuery 針對這種元素,會先設置其 css 樣式設置爲position: "absolute", visibility: "hidden", display: "block"
計算完高寬後再恢復,參見 https://github.com/jquery/jquery/blob/master/src/css.js#L460
如果遇到這種特殊情況,可以參考 jQuery 寫一個類似的方法
.prop() 方法的陷阱
有次我要把一個文本框置爲只讀,寫了這麼一行 $('#text').prop('readonly', true)
結果死活不工作
找了半天才發現,正確的寫法是這樣 $('#text').prop('readOnly', true)
,如果你居然看不出兩者的差別,那麼悄悄提示你:注意大小寫!
翻了一下相關的文檔,原來只讀屬性的正確拼法確實是 readOnly,可是在 jQuery 裏面上一段代碼卻能正常工作
於是到 jQuery 源碼裏面一找才發現,還有這麼一段 https://github.com/jquery/jquery/blob/master/src/attributes.js#L466
jQuery.each([ "tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function() { jQuery.propFix[ this.toLowerCase() ] = this; });
從這裏也能看到,jQuery 的成熟度真是難以超越,因爲他把我們都慣壞了……
考慮到這段代碼比較簡單,我厚顏無恥地抄襲了一下然後給 Zepto 提了一個 pull request ,如果你們喜歡這種無腦的用法,可以去評論表達支持(記得用英文)
.show() 的動畫效果
如果沒有 fx_mehods 模塊的話,.show() 方法是不支持動畫的,不過有了這模塊後,動畫的支持還是有點小問題,比如這麼一段 HTML
<div style="background:black;opacity:0.7;display:none"> test</div>
如果你調用 $('div').show('fast')
,那麼動畫完成後你看到的不會是一個半透明的元素,而是全黑不透明的
因爲 Zepto 的 .show() 動畫實現的很簡單,沒有高寬的變化,而是將透明度從 0 逐漸變爲 1,所以元素上原來設置的透明度就被替代了。
這種情況下,可以用 .fadeIn() 方法來替代 .show()
轉賬來源 http://chaoskeh.com/blog/some-experience-of-using-zepto.html