Zeptoソース分析4-コアモジュール入口
$()
とZオブジェクト作成Zepto Core APIの最初の方法
$()
は、その公式解釈に従う.Create a Zepto collection oject by performing a CSS selector、wrapping DOM nodes、or creating elements from an HTML string.
CSSセレクタを使用したり、DOMノードを包装したり、HTMLセグメントからZeptoセットオブジェクトを作成します.ここはコアモジュールの入口であり、
src/zepto.js
の中の次のような呼び出しに対応しています. //\ Line 231
$ = function(selector, context) {
return zepto.init(selector, context);
};
//\ Line 186
zepto.init = function(selector, context) {
//\
/*\ 1 */ return zepto.Z();
/*\ 2 */ return $(context).find(selector);
/*\ 3 */ return $(document).ready(selector);
/*\ 4 */ return selector;
/*\ 5 */ return $(context).find(selector);
/*\ 6 */ return zepto.Z(dom, selector);
};
$
は、緊縮エントリのzepto.init
の別名であり、このような関数伝達により、zepto.init
の値パラメータは最大2つとなる.zepto.init
関数に入ると、中間の処理の詳細を無視して、最終的な輸出は上記の6つの種類があることに気づき、第1のものは第6のものとZ
というオブジェクトの作成プロセスに陥り、$.fn
オブジェクトはconstructor
に向けられ、zepto.Z
オブジェクトのプロトタイプが設定されている.ここはZeptoの構造組織方式です. //\ Line 172
zepto.Z = function(dom, selector) {
return new Z(dom, selector);
};
//\ Line 408
$.fn = {
constructor: zepto.Z,
//\ ...
}
//\ Line 938
zepto.Z.prototype = Z.prototype = $.fn;
Zeptoコードを読み込んだら、ブラウザで以下のように調整して、Zオブジェクトの生成を初歩的に認識することができます.//\ Zepto , $.fn
> $().__proto__ === $.fn
true
//\ $ Zepto , Zepto , $.func
> Object.keys($)
(22) ["extend", "contains", "type", ... ]
//\ $.fn Zepto API, zepto.Z Z
> Object.keys($.fn)
(75) ["constructor", "length", "forEach", "reduce", ... ]
//\ Z $.fn
> $().hasClass === $.fn.hasClass
true
引き続きデバッグプロセスを行い、Zオブジェクトの本質を分析する://\ Z , Chrome “ ”
> $()
Z [selector: ""]
//\ Array
> $() instanceof Array
false
> $() instanceof Zepto.zepto.Z
true
//\ Zepto " " selector ,
> Object.keys($())
(2) ["length", "selector"]
このような「拡張配列」生成の方法は、この非常に簡明な関数であり、ここでは、Z
の次の指し示しは、this
オブジェクトである. //\ Line 128
//\ Z Constructor
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 || "";
}
したがって、構造関数を呼び出してZオブジェクトを生成する方法は、Z
に戻ります(2/3/5出口は、あるZオブジェクトの下で動作して生成されたZオブジェクトです.4出口は実際にZオブジェクトが入ってきて、直接に自身に戻ります).Zオブジェクトコンストラクタに読み込まれた2つのパラメータzepto.init
とdom
は、Zeptoにおいても、Zコンストラクタの単純性を保証するための明確な仕様がある.selector
の生成とdom
の取得範囲selector
の生成は、以下のいくつかの正規表現とその生成関数dom
に厳密に依存し、このステップは比較的に難しく、つまり、元のdom構造を対応するZオブジェクトにマッピングする関係である. //\ Line 10
//\ HTML , Group 1 (\w+|!) , : div
fragmentRE = /^\s*]*>/,
//\ , : /
singleTagRE = /^(?:|)$/,
//\ ,Group 1 / Gruop 2 Group 1
tagExpanderRE = /]*)\/>/gi,
//\ Line 140
zepto.fragment = function(html, name, properties) {
var dom, nodes, container;
//\ singleTagRE document , $()
if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1));
if (!dom) {
//\ replace html
if (html.replace) html = html.replace(tagExpanderRE, "$2>");
//\ name ,
if (name === undefined) name = fragmentRE.test(html) && RegExp.$1;
//\ name containers , *
if (!(name in containers)) name = "*";
//\ containers , html
container = containers[name];
container.innerHTML = "" + html;
//\ container , dom Z
//\ :https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild
dom = $.each(slice.call(container.childNodes), function() {
container.removeChild(this);
});
}
//\
if (isPlainObject(properties)) {
//\ dom Z , properties $(dom)
nodes = $(dom);
$.each(properties, function(key, value) {
if (methodAttributes.indexOf(key) > -1) nodes[key](value);
else nodes.attr(key, value);
});
}
//\ dom
return dom;
};
分析期間のいくつかの疑問:次の3つの呼び出し方式の結果が同じであることを保証するために、
> $.zepto.fragment("
") Z [div, selector: ""] > $.zepto.fragment("
") Z [div, selector: ""] > $.zepto.fragment("
") Z [div, selector: ""]
container
containers
:
containers
name
innerHTML
, ,div
.//\ Line 22 containers = { tr: document.createElement("tbody"), tbody: table, thead: table, tfoot: table, td: tableRow, th: tableRow, "*": document.createElement("div") },
で3 のパラメータタイプを する は、 zepto.fragment
とisObject
:isPlainObject
だけでなくisPlainObject
を しており、 などを けるために のObjectと される がある は、ここでオブジェクトのプロトタイプを する.//\ Line 74 function isPlainObject(obj) { return ( isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype ); }
isObject
は、DOMよりもずっと であり、 のSelectorモジュールを しないと、selector
というブラウザ によってサポートされているセレクタの である.(Zeptoソースコードの のDocument.querySelectorAll()
は、モダリティを するために く われています.ここで するselector
は、 にはZオブジェクトのselector
です.)selector
の6つの
のクッションがあって、やっとzepto.init
に ることができます.その6つの に するZオブジェクトの または を します.この 、zepto.init = function(selector, context) { var dom //\ 1: Falsy , Z ( ) //\ : $() / $(undfined) if (!selector) return zepto.Z() //\ selector else if (typeof selector == 'string') { //\ selector '") //\ 6 if (selector[0] == ' alert("DONE)) else if (isFunction(selector)) return $(document).ready(selector) //\ 5: Z ( ) //\ JSON.stringify($($('p'))) === JSON.stringify($('p')) else if (zepto.isZ(selector)) return selector //\ , else { //\ Selector , Falsy , $([$('div'), $('body')]) if (isArray(selector)) dom = compact(selector) //\ , 6 else if (isObject(selector)) dom = [selector], selector = null //\ 2/3 else if (fragmentRE.test(selector)) dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null else if (context !== undefined) return $(context).find(selector) else dom = zepto.qsa(document, selector) } //\ 6, dom / selector Z ( ) return zepto.Z(dom, selector) }
zepto.init
オブジェクトとZオブジェクトとの の を えることもでき、dom
はZオブジェクト の Zオブジェクトである.dom
とzepto.init
は してこそ、zepto.fragment
が のタイプに ることができることを に することができ、 のタイプの と の 、これもZeptoの である.