讀zepto核心源碼學(xué)習(xí)JS筆記(3)--zepto.init()

zepto.init()

1. 首先是第一種情況,selector為空

既然是反向分析,那我們先看看這句話的代碼;

`if (!selector) return zepto.Z()`

這里的返回值為zepto.Z();那我們繼續(xù)往上找zepto.Z()函數(shù)
java zepto.Z = function(dom, selector) { return new Z(dom, selector) }
這個(gè)函數(shù)仍然擁有一個(gè)返回值,Z函數(shù)的實(shí)例,同樣的道理,我們繼續(xù)去找Z() ;
```java
function Z(dom, selector) {
var i, len = dom ? dom.length : 0
for (i = 0; i < len; i++) this[i] = dom[i]
this.length = len
this.selector = selector || ''
}
根據(jù)以上代碼可以分析出,當(dāng)沒(méi)有參數(shù)時(shí),會(huì)得到一個(gè)length:0,selector:''的對(duì)象.

QQ截圖20170608110900.png

2. 當(dāng)selector為字符串的時(shí)候,又分為三種情況;

同樣的,我們先看看這句話的代碼
```java
else if (typeof selector == 'string') {
    selector = selector.trim()
}
```
  • 第一種,當(dāng)selector為html片段

    if (selector[0] == '<' && fragmentRE.test(selector))
          dom = zepto.fragment(selector, RegExp.$1, context), selector = null
    
    • (1) fragmentRE.test(selector)

      這里的fragmentRE是Zepto函數(shù)在之前定義的一段正則;

      //<div>erfwef</div>  取出<div>
      fragmentRE = /^\s*<(\w+|!)[^>]*>/,
      
    • (2) zepto.fragment(selector, RegExp.$1, context)

      • RegExp.$1
        RegExp.$1為RegExp的一個(gè)屬性,指的是與正則表達(dá)式匹配的第一個(gè) 子匹配(以括號(hào)為標(biāo)志)字符串;
        例子:
          var r= /^(\d{4})-(\d{1,2})-(\d{1,2})$/;
          r.exec('1985-10-15');
          s1=RegExp.$1;
          s2=RegExp.$2;
          s3=RegExp.$3;
          alert(s1+" "+s2+" "+s3)//結(jié)果為1985 10 15
      
      • zepto.fragment()函數(shù)
      //對(duì)應(yīng)上面的代碼,這里第一個(gè)參數(shù)是selector,就是我們?cè)趯?xiě)代碼時(shí)的$('xxx')中的xxx,
      //name為RegExp.$1,即正則匹配的第一個(gè)()里的東西,就是標(biāo)簽元素,例如 div p  h1等
      zepto.fragment = function(html, name, properties) {
            var dom, nodes, container
            // singleTagRE仍為之前定義的變量
            //singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, 匹配值如下截圖
            //如html傳入值為<p></p>,匹配singleTagRE,則創(chuàng)建<p></p>,并調(diào)用$('<p></p>')
            if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1))
            //如果不匹配
            if (!dom) {
              //這是一段修復(fù)代碼,將<div/>之類的不正常的代碼修復(fù)成<div></div>;
              //具體的下面再講解
              if (html.replace) html = html.replace(tagExpanderRE, "<$1></$2>")
              //如果沒(méi)有標(biāo)簽名,,給他一個(gè)標(biāo)簽,fragmentRE = /^\s*<(\w+|!)[^>]*>/,
              if (name === undefined) name = fragmentRE.test(html) && RegExp.$1
              //containers = {tr': document.createElement('tbody'),tbody': table, 'thead': table, 'tfoot': table,td': tableRow, 'th': tableRow,'*': document.createElement('div')},
              //如果name值不在container范圍內(nèi),則標(biāo)簽名為div
              if (!(name in containers)) name = '*'
              //創(chuàng)建容器
              container = containers[name]
              //把html片段放入到容器中
              container.innerHTML = '' + html
              //這里調(diào)用了$.each();一會(huì)再詳細(xì)講解,這里是涉及到哪個(gè)函數(shù)我就去解析哪個(gè)函數(shù)
              //emptyArray = [], slice = emptyArray.slice,
              //所以這里的slice.call即為Array.prototype.slice.call(),能將具有l(wèi)ength屬性的對(duì)象轉(zhuǎn)成數(shù)組;
              dom = $.each(slice.call(container.childNodes), function(){
              //刪除
                container.removeChild(this)
              })
            }
            //如果properties為對(duì)象
            if (isPlainObject(properties)) {
            //$(dom)將dom轉(zhuǎn)化成zepto對(duì)象元镀;是為了方便調(diào)用其他方法椒楣;
              nodes = $(dom)
              $.each(properties, function(key, value) {
              //methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'],
              //如果設(shè)置的key在methodAttributes內(nèi),則直接調(diào)用zepto上的方法拯田;
                if (methodAttributes.indexOf(key) > -1) nodes[key](value)
                else nodes.attr(key, value)
              })
            }
            //<p><span></span></p>返回[p,span]
            return dom
      }
      
      • singleTagRE
        QQ截圖20170608135118.png
      • tagExpanderRE


        QQ截圖20170608142535.png
      • fragmentR
        QQ截圖20170608173421.png
  • 第二種 當(dāng)context有值

     else if (context !== undefined) return $(context).find(selector)
    

    這里涉及到一個(gè)方法find,是$.fn中的方法,之后做統(tǒng)一分析;

  • 第三種 沒(méi)有context;

     else dom = zepto.qsa(document, selector)
    
      zepto.qsa = function(element, selector){
          var found,
          //判斷是不是ID
          maybeID = selector[0] == '#',
          //判斷是不是css
          maybeClass = !maybeID && selector[0] == '.',
          //看是不是class和id名,如果是,將'#'或者'.'去除,然后賦值給nameOnlt;
          //否則,直接將值賦值;
          nameOnly = maybeID || maybeClass ? selector.slice(1) : selector,
          //simpleSelectorRE = /^[\w-]*$/,
          //匹配字母數(shù)字下劃線和減號(hào)的組合;
          isSimple = simpleSelectorRE.test(nameOnly)
          //如果有內(nèi)置getElementById方法,并且是id名;
      return (element.getElementById && isSimple && maybeID) ?
          //則返回element.getElementByID(nameOnly)
        ( (found = element.getElementById(nameOnly)) ? [found] : [] ) :
        //反之的話,再做一次判斷
        //若element不為元素節(jié)點(diǎn),document,DocumentFragment時(shí);為空,
        (element.nodeType !== 1 && element.nodeType !== 9 && element.nodeType !== 11) ? [] :
        //否則,將節(jié)點(diǎn)轉(zhuǎn)換成數(shù)組;
        slice.call(
        //這里是一個(gè)三元運(yùn)算符里套著另一個(gè)三元運(yùn)算符;
          isSimple && !maybeID && element.getElementsByClassName ?
          //當(dāng)為class,則調(diào)用element.getElementsByClassName(nameOnly) 
                maybeClass ? element.getElementsByClassName(nameOnly) :
                  //否則調(diào)用tagName;
                element.getElementsByTagName(selector) :
         //這個(gè)否則是最外層的判斷;
            element.querySelectorAll(selector)
        )
    }
    

3. 當(dāng)傳入的值為函數(shù)時(shí),則在dom加載后執(zhí)行它;

else if (isFunction(selector)) return $(document).ready(selector)

4. 如果selector為Z的實(shí)例對(duì)象.則返回他自己;

else if (zepto.isZ(selector)) return selector

5. 最后,又分為5種情況;

  • 如果selector為數(shù)組;

    //
    if (isArray(selector)) dom = compact(selector)
    

    這里用到了一個(gè)compact方法;

    //這里調(diào)用了一個(gè)filter方法,是在$.fn內(nèi),以后統(tǒng)一分析;
    //這個(gè)函數(shù)是去除數(shù)組中的null和undefined;
    function compact(array) { return filter.call(array, function(item){ return item != null }) }
    

    所以當(dāng)為數(shù)組的時(shí)候,去除數(shù)組中的null和undefined;

  • selector為對(duì)象

    else if (isObject(selector))
        dom = [selector], selector = null
    

    如果selector為對(duì)象,將對(duì)象變?yōu)橐粋€(gè)數(shù)組;

  • selector為html片段;則將其轉(zhuǎn)換成dom

    else if (fragmentRE.test(selector))
        dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null
    
  • 有context的時(shí)候

    else if (context !== undefined) return $(context).find(selector)
    
  • 沒(méi)有context

    else dom = zepto.qsa(document, selector)
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末叶沛,一起剝皮案震驚了整個(gè)濱河市瘪弓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蕴侧,老刑警劉巖嗤攻,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件苏研,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡欲诺,警方通過(guò)查閱死者的電腦和手機(jī)抄谐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)扰法,“玉大人蛹含,你說(shuō)我怎么就攤上這事∪洌” “怎么了浦箱?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵吸耿,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我酷窥,道長(zhǎng)咽安,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任蓬推,我火速辦了婚禮妆棒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘沸伏。我一直安慰自己糕珊,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布毅糟。 她就那樣靜靜地躺著红选,像睡著了一般。 火紅的嫁衣襯著肌膚如雪姆另。 梳的紋絲不亂的頭發(fā)上喇肋,一...
    開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音迹辐,去河邊找鬼蝶防。 笑死,一個(gè)胖子當(dāng)著我的面吹牛右核,可吹牛的內(nèi)容都是我干的慧脱。 我是一名探鬼主播渺绒,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼贺喝,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了宗兼?” 一聲冷哼從身側(cè)響起躏鱼,我...
    開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎殷绍,沒(méi)想到半個(gè)月后染苛,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡主到,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年茶行,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片登钥。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡畔师,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出牧牢,到底是詐尸還是另有隱情看锉,我是刑警寧澤姿锭,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站伯铣,受9級(jí)特大地震影響呻此,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜腔寡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一焚鲜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧放前,春花似錦恃泪、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至叽粹,卻和暖如春览效,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背虫几。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工锤灿, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人辆脸。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓但校,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親啡氢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子状囱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 經(jīng)過(guò)前面三章的鋪墊,這篇終于寫(xiě)到了戲肉倘是。在用 zepto 時(shí)亭枷,肯定離不開(kāi)這個(gè)神奇的 $ 符號(hào),這篇文章將會(huì)看看 z...
    對(duì)角另一面閱讀 596評(píng)論 1 3
  • <a name='html'>HTML</a> Doctype作用搀崭?標(biāo)準(zhǔn)模式與兼容模式各有什么區(qū)別? (1)叨粘、<...
    clark124閱讀 3,482評(píng)論 1 19
  • 這篇依然是跟 dom 相關(guān)的方法,側(cè)重點(diǎn)是跟集合元素查找相關(guān)的方法瘤睹。 讀Zepto源碼系列文章已經(jīng)放到了githu...
    對(duì)角另一面閱讀 280評(píng)論 0 0
  • 一 整體結(jié)構(gòu) 為了防止全局變量污染,zepto使用的是立即執(zhí)行函數(shù),寫(xiě)法結(jié)構(gòu)為: 其中框架的實(shí)現(xiàn)方式都是在立即執(zhí)行...
    一二三kkxx閱讀 282評(píng)論 0 1
  • 在讀未來(lái)簡(jiǎn)史時(shí)升敲,剛開(kāi)始進(jìn)步很慢,一天也就十來(lái)頁(yè)轰传,當(dāng)開(kāi)始講人文主義的時(shí)候驴党,開(kāi)始覺(jué)得作者好牛,有種縱觀全局的感覺(jué)绸吸,后來(lái)...
    小喜悅閱讀 216評(píng)論 0 0