學習zepto.js(Hello World)


Zepto是一個輕量級的針對現代高級瀏覽器的JavaScript庫, 它與jquery有着類似的api。 如果你會用jquery,那么你也會用zepto。

    昨天聽說了zepto.js,正好最近也比較閑,所以就學習一下這個著名DOM操作庫,由於本人剛接觸這個,但又不想單純的說如何使用,所以本人會按照API順序來說明方法如何使用並試着將對於源碼的理解寫上來;

$():

  與jQuery的$()幾乎一樣,但zepto的選擇器是直接使用的原生querySelectorAll(),所以,一些jQuery自定義的選擇器是不支持的,但可以添加selector.js模塊來添加10個(是的,我查了)常用的偽類選擇器;

  $()選擇器有五種用法:

  $(選擇器,[可選的上下文環境,默認document]) 

$("#id");/*document.getElementById("id")*/
$("#id time");/*document.querySelectorAll("#id time")*/
$("#id", $("head"));/*如果$('head')只有一個元素,那么就按head[0].querySelectorAll("#id")來取,否則循環$('head')取,返回的都是Zepto對象,可以傳入DOM對象*/
$("<span>hello world</span>");/*將會創建一個span標簽,*/
$("<span>",{text:'hello',id:'span-ele',css:{color:'red'}})/*創建一個id為span-ele,顯示值為hello,紅色的span標簽*/
/*以上為作為選擇器的使用方法*/
$(function () {
     //do...用過jQuery的應該都知道,這是綁定的DOMContentLoaded 事件
})

  當$變量已經存在時,如引用了jQuery,那么zepto的全局對象將不會指向$,但始終指向window.Zepto

  接下來瞅瞅內部代碼是如何實現的;

zepto函數最終返回的是一個$符號,$()的調用方式說明了$對象是一個function,所以找到了下圖中的代碼

$函數返回了上圖中的zepto.init()函數的執行結果,接收了兩個參數,第一個是選擇器(selector),第二個是上下文(context),

  如果調用時selector為空,則直接返回一個Zepto對象,

  如果selector為字符串,先去除兩端空格,然后判斷selector是否為包含html標簽的字符串,

    如果是則通過fragment方法生成一個dom對象並返回,

  當驗證selector為dom選擇器時,進一步判斷context是否為空,

    不為空時將上下文包裝為zepto對象后執行find方法,//這里包裝上下文的作用在於,傳入的上下文也許是一個dom對象,也許是一個zepto對象,而調用.find方法去執行的目的是為了兼容有些zepto對象數組下有多個對象,其實find里邊也是循環調用qsa(zepto封裝的query方法,下邊都會說)

    為空時就直接通過document調用query方法了.

  當驗證selector為一個Function對象時,就會將該方法綁定至DOMContentLoaded事件,

  zepto.isZ函數用來驗證是否為Zepto對象,如果是就直接返回,不做處理,

  其余的情況,基本上屬於將基本類型包裝為zepto對象的操作了。但有一點令我不理解的地方是,為何在最后又添加了這么一段重復的邏輯,還希望有知道的同學告訴在下。

最后返回的一個變量經過Zepto的構造函數搖身一變為Zepto對象。

接下來說一下$構造器中用到的一些其他函數;

  像通過zepto對象調用的方法,都是可以在其他地方通過$(Zepto).zepto[方法名]調用的, 如 $.zepto.qsa();

  而通過$.fn定義的,定制插件也是通過$.fn來完成的,細看代碼會發現這一句

通過$.fn[方法名]定義的為原型的方法;

通過$[方法名]定義的為類方法;

fragment():

該方法用來生成一個dom節點並返回

該方法接收最多三個參數,

  第一個為html值,可以只是一個標簽,如(“<span>”)、或一個html片段,如(“<span>hello</span>”);

  第二個為一個標識符,用來確定標簽類型,該變量主要用於對表格類元素進行一些特殊的處理,用於生成節點的一個臨時父節點(下邊會說的);

  第三個是一些屬性值,是一個json結構的,但要注意為駝峰命名法,因為zepto的精簡,所以不想jQuery那樣的寬容。

首先,方法內部判斷html是否為一個標簽:

  如果是,直接生成該標簽;

  如果不是,則通過replace方法將自關閉的標簽轉換為普通標簽,tagExpanderRE正則對象內容如下

  然后判斷name變量是否為空,如果為空,通過正則取出標簽尖括號內的值。fragmentRE內容如下:

  接下來在數組containers中循環查找看該標簽是否為表格類的標簽,如果不是就給一個【*】,【*】的臨時父容器為div。

  containers是一個數組,數組中存放的為數個createElement方法:

  可以看到這基本上是為了表格而做的- -(本人猜測是因為如果直接將div的innerHTML值賦值為”<tr></tr>“的話會在外側自動生成tbody,table等標簽的。懶得試了,應該是的。。。);

  然后就是創建臨時父容器,將html變量直接塞進去。

  接下來是一個令我凌亂的方法調用。。。(為何人家就是這么叼???)

  通過$.each循環父容器的所有子節點,然后remove該節點,而dom.removeChild()會返回該節點。(卧槽- -)$.each()方法又會返回一個數組,所以間接的就創建了dom節點。(真心感覺讀源碼漲姿勢);

  判斷properties是否為一個簡單的Object,方法如下:

  然后遍歷該object,將屬性放入dom元素中,那個判斷就不多做解釋了,因為有一些屬性被zepto做成方法了,所以直接調用該方法就可以了,這也是為什么調用$("",{text:'顯示的值'}),可以通過text設置顯示的值,需要做一些樣式處理則可以這樣寫

$("",{css:{color:'red',backgroundColor:'blue'}})/*因為style會有多個,所以css的值必須為一個json*/

  完成以后就可以返回該dom元素了。

qsa():

  跳過find方法- -以后再說。。。;

  qsa(querySelectorAll的縮寫);

  

  方法接收兩個參數,上下文,選擇器;

  $()方法中如果不傳入上下文的話,默認是這樣調用的

zepto.qsa(document,selector)

  默認將document作為上下文傳入;

  作為一個看美劇十句話能聽懂三句的人,表示一眼就能看出maybeID,maybeClass變量的含義- -;

  關於simpleSelectorRE這個正則就不貼截圖了,就是個判斷字符串中間是否有空格的。就是說看是不是不包含子選擇器的;

  上邊幾個變量都是用來判斷的,下邊是一大串的三元運算符,看着挺暈的,但是聽我解釋完,肯定會明白的(說不定就更暈了);

  首先是

    確定上下文對象支持getElementById方法,該選擇器不包含子選擇器並且選擇器開頭是個#號,這說明人家要的是個ID:XXX的標簽

      如果滿足這種情況,就調用getElementById並將返回結果放入一個數組,這也是為什么獲得jQuery對象就算是通過ID選擇器也會返回一個length為1的數組的原因,如果沒有獲取到該元素,則返回一個空數組;

    如果不滿足該條件,則判斷上下文是否為一個標簽節點,文檔對象節點或一個文檔片段節點。如果不是這三個,說明他也不會支持下邊的一些選擇器方法了。直接返回空數組(任性~);

      但如果滿足條件了,繼續進行判斷,選擇器為不包含子選擇器的(get√),並且不是通過ID選擇的(get√),而且支持getElementsByClassName的(get√),好了 繼續判斷。。。

        mabeyClass(也許是個類選擇器),那么咱們就通過getElementsByClass來取它;

        maybeNot(沒有這個變量的),那么就通過getElementByTagName來取;(的確只有這兩種了)

      然后這里是不滿足條件的處理

        直接通過上下文調用querySelectorAll()方法,這個是支持子選擇器的。(但是jQuery不是這么寫的,至少不全是,因為jQuery還有一些自己的偽類,zepto是沒有的);

  

 

 

  關於那個slice.call()只是為了將里邊返回的dom對象放在一個數組里罷了。

  先寫那么點吧,快十點了,有點略困;

  我是昨天聽說,今天才開始接觸它,如果有哪里寫的不對,還請指出來。謝謝!

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM