日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

读zepto核心源码学习JS笔记(3)--zepto.init()

發布時間:2023/11/30 javascript 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 读zepto核心源码学习JS笔记(3)--zepto.init() 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上篇已經講解了zepto.init()的幾種情況,這篇就繼續記錄這幾種情況下的具體分析.

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

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

if (!selector) return zepto.Z()

這里的返回值為zepto.Z();那我們繼續往上找zepto.Z()函數

zepto.Z = function(dom, selector) {return new Z(dom, selector) }

這個函數仍然擁有一個返回值,Z函數的實例,同樣的道理,我們繼續去找Z() ;

function Z(dom, selector) {var i, len = dom ? dom.length : 0for (i = 0; i < len; i++) this[i] = dom[i]this.length = lenthis.selector = selector || '' }

根據以上代碼可以分析出,當沒有參數時,會得到一個length:0,selector:''的對象.

2. 當selector為字符串的時候,又分為三種情況;

同樣的,我們先看看這句話的代碼

else if (typeof selector == 'string') {selector = selector.trim() }
  • 第一種,當selector為html片段
if (selector[0] == '<' && fragmentRE.test(selector))dom = zepto.fragment(selector, RegExp.$1, context), selector = null

這里有兩個知識點:
1 fragmentRE.test(selector)

這里的fragmentRE是Zepto函數在之前定義的一段正則; ```java //<div>erfwef</div> 取出<div> fragmentRE = /^\s*<(\w+|!)[^>]*>/, ```

2 zepto.fragment(selector, RegExp.$1, context)
* RegExp.$1
RegExp.$1為RegExp的一個屬性,指的是與正則表達式匹配的第一個 子匹配(以括號為標志)字符串;
例子:
java 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)//結果為1985 10 15
* zepto.fragment()函數

```java //對應上面的代碼,這里第一個參數是selector,就是我們在寫代碼時的$('xxx')中的xxx,name為RegExp.$1,即正則匹配的第一個()里的東西,就是標簽元素,例如 div p h1等,properties為執行環境. zepto.fragment = function(html, name, properties) {var dom, nodes, container// singleTagRE仍為之前定義的變量,singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, 匹配值如下截圖//如html傳入值為<p></p>,匹配singleTagRE,則創建<p></p>,并調用$('<p></p>')if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1))//如果不匹配if (!dom) {//這是一段修復代碼,將<div/>之類的不正常的代碼修復成<div></div>;具體的下面再講解if (html.replace) html = html.replace(tagExpanderRE, "<$1></$2>")//如果沒有標簽名,,給他一個標簽,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范圍內,則標簽名為divif (!(name in containers)) name = '*'//創建容器container = containers[name]//把html片段放入到容器中container.innerHTML = '' + html//這里調用了$.each();一會再詳細講解,這里是涉及到哪個函數我就去解析哪個函數,雖然看起來比較亂,但是符合我自己的邏輯線路.//emptyArray = [], slice = emptyArray.slice,所以這里的slice.call即為Array.prototype.slice.call(),能將具有length屬性的對象轉成數組;dom = $.each(slice.call(container.childNodes), function(){//刪除container.removeChild(this)})}if (isPlainObject(properties)) {nodes = $(dom)$.each(properties, function(key, value) {if (methodAttributes.indexOf(key) > -1) nodes[key](value)else nodes.attr(key, value)})}return dom

}
```

以上代碼出現了singleTagRE

  • singleTagRE

  • tagExpanderRE

  • fragmentRE

  • 第二種 當context有值
else if (context !== undefined) return $(context).find(selector)

這里涉及到一個方法find,是$.fn中的方法,之后做統一分析;

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

3. 當傳入的值為函數時,則在dom加載后執行它;

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

4. 如果selector為Z的實例對象.則返回他自己;

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

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

  • 如果selector為數組;
    java // if (isArray(selector)) dom = compact(selector)
    這里用到了一個compact方法;
    java //這里調用了一個filter方法,是在$.fn內,以后統一分析; //這個函數是去除數組中的null和undefined; function compact(array) { return filter.call(array, function(item){ return item != null }) }
    所以當為數組的時候,去除數組中的null和undefined;

  • selector為對象
    java else if (isObject(selector)) dom = [selector], selector = null
    如果selector為對象,將對象變為一個數組;
  • selector為html片段;則將其轉換成dom
    java else if (fragmentRE.test(selector)) dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null
  • 有context的時候

    else if (context !== undefined) return $(context).find(selector)
  • 沒有context
    java else dom = zepto.qsa(document, selector)

轉載于:https://www.cnblogs.com/siva-epoch/p/7161627.html

總結

以上是生活随笔為你收集整理的读zepto核心源码学习JS笔记(3)--zepto.init()的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。