javascript原生框架(二)--init构造函数的完善

完善init构造函数

+ selector类型:
    - 无效值: null undefined '' false
    - 字符串
        * 选择器:     'div' 根据选择器筛选dom元素,并以伪数组形式 存储在this上
        * html字符串 '<p>123</p><p>456</p>' '<p>' 将html字符串 转换成 html元素
    - DOM节点
    - DOM数组(伪数组)
    - function:入口函数 DOMContentLoaded
        * 使用静态属性isReady 存储 dom树是否加载完毕
        * 判断isReady值, 如果为true,就直接执行传入的函数。
        * 否则,就给document的DOMContentLoaded事件绑定处理程序,在处理程序中,先将isReady赋值为true,在执行传入的函数。
  1. 如何判断字符串为html字符串,必须满足一下条件:
    • 以’<’开头
    • 以’>’结尾
    • 最小长度为3
  1. 如何判断像数组(数组和伪数组)

    • 用length属性去判断,若具有length属性 表示为 像数组类型
    • 除了window对象以及函数对象
    • {length: 1} {4: “123”, length: 5} 稀疏数组

    • 如果为真数组,返回true

    • 如果length属性值为0(除了window对象以及函数对象),返回true
    • 如果length属性值>0, 如果对象 具有 length - 1 索引,返回true
  2. 全局对象 window特性:有一个window属性 引用 自身。

代码如下:

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
(function(global) {
var init,
document = global.document;
var moyas = function(selector) {
return new moyas.fn.init(selector);
};
moyas.fn = moyas.prototype = {
constructor: moyas,
length: 0
};
init = moyas.fn.init = function(selector) {
// handle: null undefined '' false
if(!selector) return this;
// handle: string
else if(moyas.isString(selector)){
// handle: html string '<p>123</p>'
if(moyas.isHTML(selector)){
// 怎么存储 以伪数组对象形式存储 dom元素
Array.prototype.push.apply(this, moyas.parseHTML(selector));
}
// handle: selector
else {
// 根据选择器获取dom元素
var nodelist = document.querySelectorAll(selector);
// 将结果伪数组对象 变成 真数组
var ret = Array.prototype.slice.call(nodelist);
// 借调数组对象的slice方法将数组中的所有元素 以伪数组形式存储在this上
Array.prototype.push.apply(this, ret);
}
}
// handle: dom node
else if(moyas.isDOM(selector)){
this[0] = selector;
this.length = 1;
}
// handle: dom array(伪数组对象)
else if(moyas.isArrayLike(selector)){
// 获取selector类型
var _type = Object.prototype.toString.call(selector).
slice(8, -1).toLowerCase();
// 如果不是数组类型,就 将其转换 为 真数组类型
if(_type !== 'array')
selector = Array.prototype.slice.call(selector);
Array.prototype.push.apply(this, selector);
}
// handle: function
else if(moyas.isFunction(selector)){
if(moyas.isReady){
selector();
} else {
doucment.addEventListener('DOMContentLoaded', function() {
selector();
moyas.isReady = true;
});
}
}
};
init.prototype = moyas.fn;
moyas.extend = moyas.fn.extend = function(source, target) {
var k;
target = target || this;
for(k in source){
target[k] = source[k];
}
};
// 添加工具类方法
moyas.extend({
isReady: false,
paseHTML: function(html) {
var div = document.createElement('div'),
ret = [];
div.innerHTML = html;
for(var elem = div.firstChild; elem; elem = elem.nextSibling){
if(elem.nodeType === 1) ret.push(elem);
}
return ret;
}
});
// 类型判断方法
moyas.extend({
// 判断是否为字符串类型
isString: function(obj) {
// 如果为null或undefined,返回false
// 如果typeof值为string,返回true否则返回false。
return !!obj && typeof obj === 'string';
},
isHTML: function(obj) {
return !!obj && obj.charAt(0) === '<' &&
obj.charAt(obj.length - 1) === '>' &&
obj.length >= 3;
},
isDOM: function(obj) {
return !!obj && !!obj.nodeType;
},
isFunction: function(obj) {
return !!obj && typeof obj === 'function';
},
isGlobal: function(obj) {
return !!obj && obj.window === obj;
},
isArrayLike: function(obj) {
var _type = Object.prototype.toString.call(obj).slice(8, -1).toLowerCase(),
length = !!obj && 'length' in obj && obj.length;
// 过滤 window对象和函数对象
if(moyas.isFunction(obj) || moyas.isGlobal(obj)) return false;
return _type === 'array' || length === 0 ||
typeof length === 'number' && length > 0 && (length - 1) in obj;
}
});
global.$ = global.moyas = moyas;
}(window));