zepto.init = function(selector, context) { var dom // 參數沒內容,則返回空集合 if (!selector) return zepto.Z() else if (typeof selector == 'string') { selector = selector.trim() // 若是是 html 標籤,則生成 dom 元素 // 先行檢查是否爲 < 開頭,提升正則檢測效率 if (selector[0] == '<' && fragmentRE.test(selector)) dom = zepto.fragment(selector, RegExp.$1, context), selector = null // 若是有 context,則生成 context 的對象集合,再檢索 else if (context !== undefined) return $(context).find(selector) // 以 css 規則檢索元素 else dom = zepto.qsa(document, selector) } // 若是傳參是函數,則在頁面加載完成時觸發執行 else if (isFunction(selector)) return $(document).ready(selector) // 若是給定的是 zepto 集合,直接返回 else if (zepto.isZ(selector)) return selector else { // 是數組,則過濾 null 元素 if (isArray(selector)) dom = compact(selector) // 是對象,則包在數組中 else if (isObject(selector)) dom = [selector], selector = null // If it's a html fragment, create nodes from it // 什麼狀況下邏輯會走到下面?此時 html fragment 是什麼?? else if (fragmentRE.test(selector)) dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null // If there's a context, create a collection on that context first, and select // nodes from there else if (context !== undefined) return $(context).find(selector) // And last but no least, if it's a CSS selector, use it to select nodes. else dom = zepto.qsa(document, selector) } // create a new Zepto collection from the nodes found return zepto.Z(dom, selector) }
zepto.fragment = function(html, name, properties) { var dom, nodes, container // 判斷是否空標籤,如:<a></a> <p /> if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1)) if (!dom) { if (html.replace) html = html.replace(tagExpanderRE, "<$1></$2>") // 補全雙標籤 if (name === undefined) name = fragmentRE.test(html) && RegExp.$1 if (!(name in containers)) name = '*' container = containers[name] container.innerHTML = '' + html // 使 html 字符串轉換成 dom 元素 // 將 container 內的元素集合轉換成數組,賦值給dom,並清空 container // slice.call 兩個好處:1. 轉換成數組 2. 數組拷貝 // 這裏爲何不直接將 container 置空,而是一個個移除呢?? dom = $.each(slice.call(container.childNodes), function(){ container.removeChild(this) }) } // properties 屬性賦值 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 }
規則css
/^[/w-]*$/
zepto.Z = function(dom, selector) { return new Z(dom, selector) } 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 || '' }