前言:为了搞清楚上篇文章提到的data函数,我们必须先讲angularjs的JQLite库。
angularjs有个内嵌的轻量级的jquery:jqLite,它的参数只有两种,一种是Dom元素,一种是类似html元素的字符串
JQLite定义
从定义可以看到,JQLite不支持不带html格式的字符串传入:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26function JQLite(element) {
//如果传入的参数已经是JQLite实例,那直接返回
if (element instanceof JQLite) {
return element;
}
var argIsString;
if (isString(element)) {
element = trim(element);
argIsString = true;
}
//this 有可能就是window
//如果参数是字符串 且不是以<开头
if (!(this instanceof JQLite)) {
if (argIsString && element.charAt(0) != '<') {
throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite!');
}
return new JQLite(element);
}
//字符串还需要调用jqLiteParseHTML函数解析
if (argIsString) {
jqLiteAddNodes(this, jqLiteParseHTML(element));
} else {
jqLiteAddNodes(this, element);
}
}
如果参数以<开头那还需要1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
## jqLiteParseHTML
```js
//简单的标记正则
var SINGLE_TAG_REGEXP = /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/;
function jqLiteParseHTML(html, context) {
context = context || window.document;
var parsed;
if ((parsed = SINGLE_TAG_REGEXP.exec(html))) {
//parsed[1]是类似 div 的字符串
return [context.createElement(parsed[1])];
}
//制造Fragment
if ((parsed = jqLiteBuildFragment(html, context))) {
return parsed.childNodes;
}
return [];
}
SINGLE_TAG_REGEXP中有几点知识点:
非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分时很有用。
例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式\1 \2…… 都要和正则表达式集合()一起使用,简单的说就是\1表示重复正则第一个圆括号内匹配到的内容
\2表示重复正则第二个圆括号内匹配到的内容?匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”。?等价于{0,1}。
如果符合正则SINGLE_TAG_REGEXP那就通过document.createElement来返回,否则 通过jqLiteBuildFragment
函数来构建html片段,关于jqLiteBuildFragment我们下篇文章再分析。
最后调用jqLiteAddNodes把元素放入JQLite对象中。
jqLiteAddNodes
1 | function jqLiteAddNodes(root, elements) { |
我们通过1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
```js
//try to bind to jquery now so that one can write jqLite(document).ready()
//but we will rebind on bootstrap again.
bindJQuery();
```
```js
var bindJQueryFired = false;
function bindJQuery() {
var originalCleanData;
if (bindJQueryFired) {
return;
}
//http://div.io/topic/1154
// bind to jQuery if present;
var jqName = jq(); // 调用jq方法返回jq库名称
jQuery = isUndefined(jqName) ? window.jQuery : // use jQuery (if present)
!jqName ? undefined : // use jqLite
window[jqName]; // use jQuery specified by `ngJq`
if (jQuery && jQuery.fn.on) {
jqLite = jQuery;
//扩展fn函数
//省略部分代码,
//重写了jQuery的cleanData,扩展了jQuery.fn
} else {
jqLite = JQLite;
}
angular.element = jqLite;
// Prevent double-proxying.
//阻止双代理
bindJQueryFired = true;
}
到到这里我们发现angular.element就是jqLite函数。