【zepto學習筆記01】核心方法$()(補)

前言

昨天學習了核心$(),有幾個遺留問題,咱們今天來看看吧javascript

$.each

遍歷數組/對象,將每條數據做爲callback的上下文,並傳入數據以及數據的索引進行處理,
若是其中一條數據的處理結果明確返回false,則中止遍歷,並返回elementscss

 1 $.each = function (elements, callback) {
 2     var i, key
 3     if (likeArray(elements)) {
 4         for (i = 0; i < elements.length; i++) {
 5             if (callback.call(elements[i], i, elements[i]) === false)
 6                 return elements;
 7         }
 8     } else {
 9         for (key in elements) {
10             if (callback.call(elements[key], key, elements[key]) === false)
11                 return elements;
12         }
13     }
14     return elements
15 }

這個方法自己實現比較簡單,咱們就不追究了,咱們看看裏面用到了一個likeArrayhtml

1 function likeArray(obj) {
2     return typeof obj.length == 'number'
3 }

這個方法咱們就說完了,下面會用到的因此這裏就先提出來html5

zepto.fragment

首先,他的調用時這個樣子的:java

dom = zepto.fragment(selector.trim(), RegExp.$1, context)

傳入html字符串,第二個參數爲尋找到的name,第三個是上下文,咱們先來看看這個正則node

var fragmentRE = /^\s*<(\w+|!)[^>]*>/;

咱們來隨便寫一段代碼測試下編程

1 //HTML代碼片段的正則
2 var fragmentRE = /^\s*<(\w+|!)[^>]*>/;
3 var str = '<div><span>fdfdsdf</span></div>';
4 console.log(RegExp.$1);
5 console.log(fragmentRE.test(str));
6 console.log(RegExp.$1);
7 console.log(fragmentRE.exec(str));

這段代碼的結果以下,RegExp.$1應該是取得最近一次匹配的標籤
因此這裏傳入的參數就是字符串和最外層標籤名了,咱們繼續往下走數組

而後他這裏來了一個html修復,向只寫了<div>沒結尾的會補全app

1 var tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig;
2 var str = '<p class="ddd"/>';
3 console.log(tagExpanderRE.exec(str));
4 console.log(str.replace(tagExpanderRE, "<$1></$2>"));

由於下面要用到name,而若是沒有傳入name參數,name就會被指定相關值,設值方式與上面一致dom

1 if (name === undefined) name = fragmentRE.test(html) && RegExp.$1

如今設值容器標籤名,由於table狀況有所不一樣因此這裏單獨對table作了處理,其它的容器都是div

 1 var table = document.createElement('table');
 2 var tableRow = document.createElement('tr');
 3 var containers = {
 4     'tr': document.createElement('tbody'),
 5     'tbody': table,
 6     'thead': table,
 7     'tfoot': table,
 8     'td': tableRow,
 9     'th': tableRow,
10     '*': document.createElement('div')
11 };
12 var container.innerHTML = '' + html //將html代碼片段放入容器

而後依次取出容器中的dom結構,這裏用到了each方法,咱們上面已經說明了
這個方法反正就是將dom中的全部children刪除了,而後返回

 1 var table = document.createElement('table');
 2 var tableRow = document.createElement('tr');
 3 var containers = {
 4     'tr': document.createElement('tbody'),
 5     'tbody': table,
 6     'thead': table,
 7     'tfoot': table,
 8     'td': tableRow,
 9     'th': tableRow,
10     '*': document.createElement('div')
11 };
12 
13 function likeArray(obj) {
14     return typeof obj.length == 'number'
15 }
16 var $ = {};
17 var slice = [].slice;
18 //slice() 方法可提取字符串的某個部分,並以新的字符串返回被提取的部分。
19 //var str = "Hello happy world!"
20 //document.write(str.slice(6, 11)); //happy
21 
22 $.each = function (elements, callback) {
23     var i, key
24     if (likeArray(elements)) {
25         for (i = 0; i < elements.length; i++) {
26             if (callback.call(elements[i], i, elements[i]) === false)
27                 return elements;
28         }
29     } else {
30         for (key in elements) {
31             if (callback.call(elements[key], key, elements[key]) === false)
32                 return elements;
33         }
34     }
35     return elements
36 }
37 var name = '*', html = '<div><span></spam></div>';
38 var container = containers[name];
39 container.innerHTML = html;
40 
41 var dom = $.each(slice.call(container.childNodes), function () {
42     container.removeChild(this);
43 })
44 console.log(container);
45 console.log(dom);

這裏只清空container,咱們的dom仍是在的,並真資格的編程了dom數組了

這裏dom其實基本搞完了,完了能夠對屬性進行設置,其中就用到了zepto屬性設置的方法了,咱們這裏暫時無論他

1 if (isPlainObject(properties)) {
2     nodes = $(dom) //將dom轉成zepto對象,爲了方便下面調用zepto上的方法
3     //遍歷對象,設置屬性
4     $.each(properties, function (key, value) {
5         //若是設置的是'val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset',則調用zepto上相對應的方法
6         if (methodAttributes.indexOf(key) > -1) nodes[key](value)
7         else nodes.attr(key, value)
8     })
9 }

最後返回了咱們建立好的dom數組,因此咱們就可使用zepto.Z將之封裝了

這個完了,咱們來看看咱們的zepto.qsa

zepto.qsa

這個方法用做選擇器,這個直接調用的html5 javascript選擇元素的方法

 1 zepto.qsa = function (element, selector) {
 2     var found
 3     //當element爲document,且selector爲ID選擇器時
 4     return (isDocument(element) && idSelectorRE.test(selector)) ?
 5     //直接返回document.getElementById,RegExp.$1爲ID的值,當沒有找節點時返回[]
 6     ((found = element.getElementById(RegExp.$1)) ? [found] : []) :
 7     //當element不爲元素節點或者document時,返回[]
 8     (element.nodeType !== 1 && element.nodeType !== 9) ? [] :
 9     //不然將獲取到的結果轉成數組並返回
10     slice.call(
11     //若是selector是標籤名,直接調用getElementsByClassName
12     classSelectorRE.test(selector) ? element.getElementsByClassName(RegExp.$1) :
13     //若是selector是標籤名,直接調用getElementsByTagName
14     tagSelectorRE.test(selector) ? element.getElementsByTagName(selector) :
15     //不然調用querySelectorAll
16     element.querySelectorAll(selector))
17 }

這個方法我最後發現比較簡單,就是選擇器,咱們這裏就無論他了

結語

咱們今天暫時到這,下次再繼續

相關文章
相關標籤/搜索