昨天學習了核心$(),有幾個遺留問題,咱們今天來看看吧javascript
遍歷數組/對象,將每條數據做爲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
首先,他的調用時這個樣子的: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
這個方法用做選擇器,這個直接調用的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 }
這個方法我最後發現比較簡單,就是選擇器,咱們這裏就無論他了
咱們今天暫時到這,下次再繼續