javascript原生框架(五)--文档处理模块

appendTo方法

  • 语法:.appendTo(target)
    • target类型 选择器、dom元素、dom数组
    • 统一target类型 为 moyas对象:为了方便操作
  • 实现思路
    • 统一target类型,定义新增节点变量node,临时存储要分配的节点
    • 定义ret数组变量,用来存储总共分配出去的节点
    • 遍历this上的每一个dom元素,在遍历target上的每一个dom元素
    • 首先判断当前dom元素是否为target上的第一个dom元素
    • 如果为真,就不克隆节点,直接将要被添加的节点赋值给node
    • 如果为假,就要深克隆节点,在赋值给node
    • 使用遍历target当前的dom元素 追加 指定节点node
    • 两层循环结束,操作完成。
    • 最后将ret转换成moyas对象,作为appendTo方法的返回值。实现链式编程

append方法

  1. 语法:.append(source);
  2. 功能:将source上的所有dom元素 追加到 moyas对象 上
  3. 实现思路
    • 统一source类型,为moyas对象。
    • source.appendTo(this)
    • return this;

prependTo方法

  1. 语法:.prependTo(target);
  2. 功能:将moyas对象上的每一个dom元素 追加到 target 最前边 insertBefore
  3. 实现思路
    • 统一target类型, 为 moyas对象
    • 定义node变量,临时存储被追加的节点。定义ret数组,存储所有被追加的节点
    • 先遍历target上的每一个dom元素,
    • 定义变量firstChild,临时存储当前目标dom元素的第一个子节点,在遍历this上每一个dom元素
    • 判断当前遍历的dom是否为target上的第一个dom元素
    • 如果为真,此时不需要克隆节点
    • 否则,要深克隆节点
    • 将上述得到的节点,push到ret内
    • 调用insertBefore方法 追加 节点,此时第一个参数为追加新的节点,第二个参数为 firstChild
      在 firstChild 之前追加 新节点。
    • 两层循环结束,操作完成
    • 将ret转换成moyas对象,作为prependTo方法的返回值。实现链式编程。

prepend方法

  1. 语法:.prepend(source);
  2. 功能:把source上的所有的dom元素,添加到this上的最前边
  3. 实现思路:
    • 统一source类型,为moyas对象
    • 通过source调用prependTo方法,将source上的所有dom添加到this上的最前边
    • return this实现链式编程

next方法

  1. 功能:获取moyas对象上所有dom元素的下一个兄弟元素(nextSibling)
  2. 语法:.next(); 返回值类型:moyas对象
  3. 实现思路
    • 定义ret数组,存储所有dom的下一个兄弟元素
    • 遍历this上的所有dom元素
    • 遍历当前dom元素下面的所有兄弟,如果类型为 元素,将此元素存储ret内,结束循环。
    • 两层循环结束,将ret转换成moyas对象,作为next方法的返回值。

nextAll方法

  1. 功能:获取moyas对象上所有dom元素下面的所有兄弟元素(nextSibling)
  2. 语法:.nextAll(); 返回值类型:moyas对象
  3. 实现思路
    • 定义ret数组,存储所有dom下面的所有兄弟元素
    • 遍历this上的所有dom元素
    • 遍历当前dom元素下面的所有兄弟节点,如果类型为 元素,将此元素存储ret内。
    • 两层循环结束,将ret去重后,转换成moyas对象,作为nextAll方法的返回值。

before方法

  1. 功能:
  2. 语法: .before(source)
  3. 实现思路
    • 统一source类型为 moyas对象
    • 遍历this上的每一个dom元素
    • 在遍历source上的每一个dom元素
    • 判断当前遍历this的dom元素的 索引是否为0
    • 如果为0,不需要拷节点
    • 否则要深拷贝节点
    • 先拿到当前遍历this的dom元素的父节点,调用insertBefore方法在其前面添加上面得到的新节点
    • 两层循环完毕,操作完成
    • return this实现链式编程

after方法(选做)

  1. 功能:
  2. 语法: .after(source)
  3. 实现思路
    • 定义nextSibling变量,存储dom元素的下一个兄弟节点
    • 统一source类型为 moyas对象
    • 遍历this上的每一个dom元素
    • 在遍历source上的每一个dom元素
    • 判断当前遍历this的dom元素的 索引是否为0
    • 如果为0,不需要拷节点
    • 否则要深拷贝节点
    • 先拿到当前遍历this的dom元素的父节点,调用insertBefore方法在nextSibling前面添加上面得到的新节点
    • 两层循环完毕,操作完成
    • return this实现链式编程

remove方法

  1. 功能:将筛选出来的所有dom元素 删除掉
  2. 实现思路
    • 遍历this上的所有dom元素
    • 获取当前dom元素的父节点,调用removeChild方法删除自己
    • 循环结束,返回this。

empty方法

  1. 功能:将筛选出来的所有dom元素 清空后代节点。
  2. 实现思路
    • 遍历this上的所有dom元素
    • 直接给当前dom元素的innerHTML属性赋值为 空字符串
    • 循环结束,返回this, 实现链式编程。

prev方法

prevAll方法

moyas.unique方法

  1. 功能:实现数组元素去重
  2. 语法:var newRet = moyas.unique(arr);
  3. 实现思路
    • 定义空数组对象ret。存储去重后元素
    • 遍历原数组,如果当前遍历到的元素在ret中不存在,就添加到ret内
    • 循环结束,ret存储的就是去重后的元素
    • 返回ret
  4. 兼容IE8 indexOf方法
    • 首先判断当前浏览器是否支持indexOf方法
    • 如果不支持,就给数组对象的原型添加 indexOf方法
    • 遍历this上的所有元素
    • 如果遍历到的当前元素 和 指定参数值 相同,就直接返回其 索引值。结束循环
    • 如果在整个上述循环都没有返回值,那么表示不存在指定参数值,就返回 -1。

详细代码

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
moyas.extend({
unique: function(arr) {
// 存储去重后的结果
var ret = [];
// 遍历原数组arr
moyas.each(arr, function() {
// 判断ret是否存在当前遍历到的元素
// 如果不存在将其添加到ret中
if(ret.indexOf(this) === -1) ret.push(this);
});
// 将ret返回
return ret;
}
});
// 兼容数组对象的indexOf方法
(function() {
// 如果浏览器不支持indexOf方法
// 那么就给数组对象的原型添加indexOf方法
if(!Array.prototype.indexOf){
Array.prototype.indexOf = function(val) {
// 遍历this
for(var i = 0,l = this.length; i < l; i++){
// 如果遍历到的当前元素和val相同,返回其索引值
if(this[i] == val) return i;
}
// 表示具有指定val元素,返回 -1
return -1;
};
}
}());

具体方法代码

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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
moyas.extend({
unique: function(arr) {
// 存储去重后的结果
var ret = [];
// 遍历原数组arr
moyas.each(arr, function() {
// 判断ret是否存在当前遍历到的元素
// 如果不存在将其添加到ret中
if(ret.indexOf(this) === -1) ret.push(this);
});
// 将ret返回
return ret;
}
});
moyas.fn.extend({
appendTo: function(target) {
var node,
ret = [];
// 统一target类型 为moyas对象(为了方便操作)
target = moyas(target);
// 遍历this上的每一个dom元素
this.each(function(v) {
// 在遍历目标dom元素
target.each(function(t, i) {
// 如果当前dom元素为 目标上的第一个.不拷贝节点
// 否则拷贝节点
node = i === 0 ? v : v.cloneNode(true);
// 将被追加的节点,添加到ret内
ret.push(node);
// 将节点追加到指定的目标dom元素上.
t.appendChild(node);
});
});
// 将每一个添加的dom元素,转换成moyas对象返回,实现链式编程
// 原因:在添加样式时,如果不这样做的话,只会给没克隆的节点添加样式.
return moyas(ret);
},
append: function(source) {
source = moyas(source);
source.appendTo(this);
return this;
},
prependTo: function(target) {
var node,
firstChild,
self = this,
ret = [];
target = moyas(target);
// 遍历target上的每一个目标dom元素
target.each(function(elem, i) {
// 缓存当前目标dom元素的第一个子节点
firstChild = elem.firstChild;
// 在遍历this上的每一个dom元素
self.each(function(dom) {
// 判断是否目标上第一个dom元素
// 如果是,不需要克隆节点
// 否则需要深克节点
// 将得到的节点赋值给node
node = i === 0 ? dom : dom.cloneNode(true);
// 将上面得到的节点添加到ret中
ret.push(node);
// 使用insertBefor给当前目标元素,在firstChild添加node节点
elem.insertBefore(node, firstChild);
});
});
return moyas(ret);
},
prepend: function(source) {
source = moyas(source);
source.prependTo(this);
return this;
},
next: function() {
// 存储所用dom的下一个兄弟元素
var ret = [];
// 遍历this上的所有dom元素
this.each(function() {
// 在遍历当前dom元素下面所有的兄弟元素
for(var node = this.nextSibling; node ; node = node.nextSibling){
// 如果当前兄弟节点,为元素节点
// 即为结果,将其添加ret内,并结束循环
if(node.nodeType === 1){
ret.push(node);
break;
}
}
});
// 将ret转换成moyas对象,返回
return moyas(ret);
},
nextAll: function() {
var ret = [],
node;
this.each(function() {
for(node = this.nextSibling; node ; node = node.nextSibling){
if(node.nodeType === 1) ret.push(node);
}
});
return moyas(moyas.unique(ret));
},
before: function(source) {
var node;
source = moyas(source);
this.each(function(dom, i) {
source.each(function(elem) {
node = i === 0 ? elem : elem.cloneNode(true);
// 获取dom的父节点,调用insertBefore方法在dom前添加新的子节点node
dom.parentNode.insertBefore(node, dom);
});
});
return this;
},
after: function(source) {
var node,
nextSibling;
source = moyas(source);
this.each(function(dom, i) {
nextSibling = dom.nextSibling;
source.each(function(elem) {
node = i === 0 ? elem : elem.cloneNode(true);
// 获取dom的父节点,调用insertBefore方法在dom前添加新的子节点node
dom.parentNode.insertBefore(node, nextSibling);
});
});
return this;
},
remove:function () {
return this.each(function () {
this.parentNode.removeChild(this);
});
},
prev:function () {
var ret=[],
node;
this.each(function () {
for (node = this.previousSibling;node;node=node.previousSibling){
if (node.nodeType === 1){
ret.push(node);
break;
}
}
});
return itcast(ret);
},
prevAll:function () {
var ret=[],
node;
this.each(function () {
for (node = this.previousSibling;node;node=node.previousSibling){
if (node.nodeType === 1){
ret.push(node);
}
}
});
return itcast(itcast.unique(ret));
},
empty:function () {
return this.each(function () {
this.innerHTML='';
})
}
});