从面向过程到面向对象
# 从面向过程到面向对象
原则: 先写出普通的写法,然后改成面向对象写法
- 普通方法变型
- 尽量不要出现函数嵌套函数
- 可以有全局变量
- 把onload中不是赋值的语句放到单独函数中
- 改成面向对象
- 全局变量就是属性
- 函数就是方法
onload
中创建对象- 改this指向问题 [TOC]
# 一、传统的过程式编写选项卡
//普通写法
window.onload = function(){
var oParent = document.getElementById('div1');
var aInput = oParent.getElementsByTagName('input');
var aDiv = oParent.getElementsByTagName('div');
for(var i=0;i<aInput.length;i++){
aInput[i].index = i;
aInput[i].onclick = function(){
for(var i=0;i<aInput.length;i++){
aInput[i].className = '';
aDiv[i].style.display = 'none';
}
this.className = 'active';
aDiv[this.index].style.display = 'block';
};
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1.1 先变型
- 尽量不要出现函数嵌套函数
- 可以有全局变量
- 把
onload
中不是赋值的语句放到单独函数中
var oParent = null;
var aInput = null;
var aDiv = null;
window.onload = function(){
oParent = document.getElementById('div1');
aInput = oParent.getElementsByTagName('input');
aDiv = oParent.getElementsByTagName('div');
init();
};
function init(){
for(var i=0;i<aInput.length;i++){
aInput[i].index = i;
aInput[i].onclick = change;
}
}
function change(){
for(var i=0;i<aInput.length;i++){
aInput[i].className = '';
aDiv[i].style.display = 'none';
}
this.className = 'active';
aDiv[this.index].style.display = 'block';
}
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
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
# 1.2 改成面向对象
- 全局变量就是属性
- 函数就是方法
onload
中创建对象- 改
this
指向问题 : 事件或者是定时器,尽量让面向对象中的this
指向对象
oDiv.onclick = function(){
this : oDiv
};
oDiv.onclick = show;
function show(){
this : oDiv
}
oDiv.onclick = function(){
show();
};
function show(){
this : window
}
oDiv.onclick = this.change;
//this.change函数是事件直接执行的函数
//this指向的是oDiv
//这里不加括号是事件触发的时候自然会调用,这里不需要(也不能加,加了就立即调用了)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 二、面向对象的选项卡
window.onload = function(){
var t1 = new Tab();//注意第一个字母是大写
t1.init();
};
function Tab(){
this.oParent = document.getElementById('div1');
this.aInput = this.oParent.getElementsByTagName('input');
this.aDiv = this.oParent.getElementsByTagName('div');
}
Tab.prototype.init = function(){
var This = this;
for(var i=0;i<this.aInput.length;i++){
this.aInput[i].index = i;
this.aInput[i].onclick = function(){
This.change(this);//这里的this是按钮,This是对象
};
}
};
//var _this = this;
////这个匿名函数是事件直接执行的事件函数
//oDiv.onclick = function() {
////现在这个change函数是被_this调用的,而不是oDiv的事件,所以change函数内部this指向_this,加括号是调用
// _this.change();
//}
Tab.prototype.change = function(obj){
for(var i=0;i<this.aInput.length;i++){
this.aInput[i].className = '';
this.aDiv[i].style.display = 'none';
}
obj.className = 'active';
this.aDiv[obj.index].style.display = 'block';
};
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
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
# 三、控制多个选项卡自动播放
window.onload = function(){
var t1 = new Tab('div1');
t1.init();
t1.autoPlay();
var t2 = new Tab('div2');
t2.init();
t2.autoPlay();
};
//在前面的基础上添加
Tab.prototype.autoPlay = function(){
var This = this;
setInterval(function(){
if(This.iNow == This.aInput.length-1){
This.iNow = 0;
}
else{
This.iNow++;
}
for(var i=0;i<This.aInput.length;i++){
This.aInput[i].className = '';
This.aDiv[i].style.display = 'none';
}
This.aInput[This.iNow].className = 'active';
This.aDiv[This.iNow].style.display = 'block';
},2000);
};
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
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
学会了吗
让我们再来巩固一下
# 四、用面向对象编写拖拽
window.onload = function(){
var oDiv = document.getElementById('div1');
var disX = 0;
var disY = 0;
oDiv.onmousedown = function(ev){
var ev = ev || window.event;
disX = ev.clientX - oDiv.offsetLeft;
disY = ev.clientY - oDiv.offsetTop;
document.onmousemove = function(ev){
var ev = ev || window.event;
oDiv.style.left = ev.clientX - disX + 'px';
oDiv.style.top = ev.clientY - disY + 'px';
};
document.onmouseup = function(){
document.onmousemove = null;
document.onmouseup = null;
};
return false;
};
};
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 4.1 变个型
var oDiv = null;
var disX = 0;
var disY = 0;
window.onload = function(){
oDiv = document.getElementById('div1');
init();
};
function init(){
oDiv.onmousedown = fnDown;
}
function fnDown(ev){
var ev = ev || window.event;
disX = ev.clientX - oDiv.offsetLeft;
disY = ev.clientY - oDiv.offsetTop;
document.onmousemove = fnMove;
document.onmouseup = fnUp;
return false;
}
function fnMove(ev){
var ev = ev || window.event;
oDiv.style.left = ev.clientX - disX + 'px';
oDiv.style.top = ev.clientY - disY + 'px';
}
function fnUp(){
document.onmousemove = null;
document.onmouseup = null;
}
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
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
# 4.2 再改成面向对象
window.onload = function(){
var d1 = new Drag('div1');
d1.init();
};
function Drag(id){
this.oDiv = document.getElementById(id);
this.disX = 0;
this.disY = 0;
}
Drag.prototype.init = function(){
var This = this;
this.oDiv.onmousedown = function(ev){
var ev = ev || window.event;
This.fnDown(ev);
return false;
};
};
//ev只能在事件函数中使用,不能在function内使用
Drag.prototype.fnDown = function(ev){
var This = this;
this.disX = ev.clientX - this.oDiv.offsetLeft;
this.disY = ev.clientY - this.oDiv.offsetTop;
document.onmousemove = function(ev){
var ev = ev || window.event;
This.fnMove(ev);
};
document.onmouseup = this.fnUp;
};
Drag.prototype.fnMove = function(ev){
this.oDiv.style.left = ev.clientX - this.disX + 'px';
this.oDiv.style.top = ev.clientY - this.disY + 'px';
};
Drag.prototype.fnUp = function(){
document.onmousemove = null;
document.onmouseup = null;
};
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
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
# 五、类
/*
拖拽:
1. 鼠标摁下可以开始拖拽
2. 记录摁下时的鼠标位置 和 元素位置
3. 移动后获取到鼠标的新位置
4. 用鼠标新位置 - 摁下时的鼠标位置 = 鼠标移动距离
5. 元素当前位置 = 鼠标移动距离 + 摁下时元素位置
*/
class Drag extends Event {
// 构造函数
constructor(el){
// 在构造函数中使用时,super关键字将单独出现,并且必须在使用this关键字之前使用。
// super关键字也可以用来调用父对象上的函数。
super();
this.el = el;
// 鼠标摁下时的元素的位置
this.startOffset = {};
// 鼠标摁下时鼠标的坐标
this.startPoint = {};
let move = (e)=>{
this.move(e);
};
let end = (e)=>{
document.removeEventListener("mousemove",move);
document.removeEventListener("mouseup",end);
this.end(e);
};
el.addEventListener("mousedown",(e)=>{
this.start(e);
document.addEventListener("mousemove",move);
document.addEventListener("mouseup",end);
});
}
// 摁下时的处理函数
start(e){
let {el} = this;
this.startOffset = {
x: el.offsetLeft,
y: el.offsetTop
};
this.startPoint = {
x: e.clientX,
y:e.clientY
};
this.trigger("dragstart",e,el);
}
//移动时的处理函数
move(e){
let {el,startOffset,startPoint} = this;
let nowPoint = {
x: e.clientX,
y: e.clientY
};
let dis = {
x: nowPoint.x - startPoint.x,
y: nowPoint.y - startPoint.y
}
el.style.left = dis.x + startOffset.x + "px";
el.style.top = dis.y + startOffset.y + "px";
// 因为这里el已经赋值为this.el,就不用写成this.el了
this.trigger("drag",e,el);
}
end(e){
this.trigger("dragend",e,this.el);
}
}
(function(){
let box = document.querySelector("#box");
let dragBox = new Drag(box);
// 原生js也是有once处理
// box.addEventListener("click",function(){
// alert(1);
// },{
// once:true
// })
// console.log(dragBox);
dragBox.on("dragstart",function(e){
//console.log(e,this);
//console.log("开始拖拽");
this.style.background = "yellow";
});
dragBox.on("dragend",function(e){
//console.log("结束拖拽");
this.style.background = "red";
});
// 第一次执行的时候是可以遍历到这个函数并执行函数,但是在handle[type]里是被取消监听的了,随后就无法遍历到这个函数了
dragBox.once("drag",function(){
console.log("drag只会出现一次");
})
})()
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
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