想快递?
像中介?

邓哥的例子
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
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewprot" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>dddd</title>
<style type="text/css">
</style>
</head>
<body>
<button id="btn">click</button>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script type="text/javascript">
var mrDeng = {
sendFlower : function (target) {
var flower = 'sunflower';
target.receiveFlower(flower);
}
};
//代理
var cstProxy = {
proxyFlower : function (target) {
this.listenMood(target,function () {
mrDeng.sendFlower(target);
})
},
// 关键是监听心情(状态)
listenMood: function (target, cb) {
var timer = setInterval(function () {
if (target.mood) {
cb();
clearInterval(timer);
}
},300);
}
}
用的是setInterval,不停监听某个状态,
一旦成功,就执行回调.保证成功率.
这应该算是监听数据了吧?
// godness
var godness = {
mood : null,
receiveFlower : function () {
// true good false bad
this.mood ? console.log('ok') : console.log('get out');
},
changeMood : function () {
this.mood = Math.random() > 0.5;
},
createMood : function () {
var self = this;
self.changeMood();
setInterval(function () {
self.changeMood();
},400);
}
}
godness.createMood();
cstProxy.proxyFlower(godness);
</script>
</body>
</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
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
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewprot" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>dddd</title>
<style type="text/css">
div{
display: inline-block;
border: 1px solid #CCCCCC;
}
div img{
width: 200px;
height: 100px;
}
</style>
</head>
<body>
<div id="app"></div>
<script type="text/javascript">
var MyImage = function (id) {
var oImg = new Image();
this.setSrc = function (src) {
oImg.src = src;
}
document.getElementById(id).appendChild(oImg);
}
//代理
var ProxyImage = (function () {
var oMyImg = new MyImage('app');
// oMyImg.setSrc('./img/1.jpg');
var oNewImage = new Image();// 这是用来代理的.代理发送请求加载资源.
// 用来监控
oNewImage.onload = function () {
oMyImg.setSrc(oNewImage.src);//加载完成时,替换过来.
}
return function (src) {
oMyImg.setSrc('./img/1.jpg');// 这是占位图,本地图
oNewImage.src = src;
}
})();
var url = 'http://s9.knowsky.com/bizhi/l/20090808/200910296%20%2841%29.jpg';
ProxyImage(url);
</script>
</body>
</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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
闭包版本
var aaaaa = (function () {
var lastTime = 0;
return function () {
if (new Date().getTime() - lastTime > 1000) {
console.log('aaa');
lastTime = new Date().getTime();
}
}
})()
btn.onclick = aaaaa;
函数工厂版本
function debounce (fun) {
var lastTime = 0;
return function () {
if (new Date().getTime() - lastTime > 1000) {
lastTime = new Date().getTime();
return fun.apply(this,arguments);
}
};
}
function aaa () {
console.log('aaa');
}
var aaaa = debounce(aaa);
btn.onclick = aaaa;
返回对象版本
function Debounce (fun) {
var lastTime = 0;
this.debounce = function () {
if (new Date().getTime() - lastTime > 1000) {
lastTime = new Date().getTime();
return fun.apply(this,arguments);
}
};
}
function aaa () {
console.log('aaa');
}
var a = new Debounce(aaa);
btn.onclick = a.debounce;
不过这样似乎没什么意思?
比起直接定义在一个对象上,lastTime 成了私有变量?
作业1.0图片懒加载多个图片加载?
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
var div = [].slice.call(document.getElementsByTagName('div'));
var MyImage = function (dom) {
var oImg = new Image();
this.setSrc = function (src) {
oImg.src = src;
}
dom.appendChild(oImg);
}
function ProxyImage (dom) {
var oMyImg = new MyImage(dom);
var newImage = new Image();
newImage.onload = function () {
oMyImg.setSrc(newImage.src);
}
this.proxy = function (src) {
oMyImg.setSrc('./img/1.jpg');
newImage.src = src;
}
}
var appSrc = new ProxyImage(div[0]);
var url = 'http://s9.knowsky.com/bizhi/l/20090808/200910296%20%2841%29.jpg';
// ProxyImage(url);
btn.onclick = function () {
appSrc.proxy(url);
}
这写的啥玩意..
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
过了几天我自己又跟着印象又写了一次,
我发现了一个差别.
我总盯着数据, 我定义一个函数,想返回的是数据.
而我看陈老师的代码, 他定义一个函数,想返回的是一个放置数据的对象,容器.
这就是面向对象的编程思维的具体表现之一?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewprot" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>dddd</title>
<style type="text/css">
.wrapper div{
width: 300px;
height: 150px;
}
.wrapper img{
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="item1"></div>
<div class="item2"></div>
<div class="item3"></div>
<div class="item4"></div>
<div class="item5"></div>
<div class="item6"></div>
<div class="item7"></div>
<div class="item8"></div>
<div class="item9"></div>
<div class="item10"></div>
</div>
<script type="text/javascript">
// 批量懒加载
// 假设 item1 和 url 是配对的
var arr = [
{class : "item1", url : "http://pic.pptbz.com/201506/2015070581208537.JPG"},
{class : "item2", url : "http://pic.pptbz.com/201506/2015070581208537.JPG"},
{class : "item3", url : "http://pic.pptbz.com/201506/2015070581208537.JPG"},
{class : "item4", url : "http://pic.pptbz.com/201506/2015070581208537.JPG"},
{class : "item5", url : "http://pic.pptbz.com/201506/2015070581208537.JPG"},
{class : "item6", url : "http://pic.pptbz.com/201506/2015070581208537.JPG"},
{class : "item7", url : "http://pic.pptbz.com/201506/2015070581208537.JPG"},
{class : "item8", url : "http://pic.pptbz.com/201506/2015070581208537.JPG"},
{class : "item8", url : "http://pic.pptbz.com/201506/2015070581208537.JPG"},
{class : "item10", url : "http://pic.pptbz.com/201506/2015070581208537.JPG"}
]
// 获取元素,
var wrapper = document.getElementsByClassName("wrapper")[0];
// 渲染图片
function myImg (url,dom) {
var img = new Image();
img.src = url;
console.log(dom);
dom.appendChild(img);
return img;
}
// 懒加载
function lazyload (arr) {
if (!Array.isArray(arr)) {
arr = [{class : arguments[1], url : arr}];
}
var len = arr.length;
for(var i = 0; i < len ; i++) {
(function (i) {
var ele = document.getElementsByClassName(arr[i].class)[0];
var img = myImg("img/1.jpg",ele);
var newImg = new Image();
newImg.onload = function () {
img.src = arr[i].url;
}
setTimeout(function () {
console.log(arr[i]);
newImg.src = arr[i].url;
},1000);
})(i);
}
}
var url = "http://pic.pptbz.com/201506/2015070581208537.JPG";
console.log(wrapper);
lazyload(arr);
</script>
</body>
</html>
作业2.0 事件累积?
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
先写一波事件点击改变属性的操作.
写得时候感觉写得挺溜的,
写完之后发现可读性很差,毫无维护性,扩展性可言..
通篇也没有用到什么面相对象的东西.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewprot" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>dddd</title>
<style type="text/css">
div{
position: absolute;
left: 100px;
top: 100px;
height: 100px;
width: 100px;
font-size: 18px;
border: 1px solid black;
}
</style>
</head>
<body>
<div>duyi</div>
<span>up</span>
<button>width up</button>
<button>height up</button>
<button>fontSize up</button>
<button>right</button>
<button>bottom</button>
<br />
<span>down</span>
<button>width down</button>
<button>height down</button>
<button>fontSize down</button>
<button>left</button>
<button>top</button>
<script type="text/javascript">
// 我希望点击,发生相应的改变
var div = document.getElementsByTagName('div')[0];
var buttonArray = document.getElementsByTagName('button');
function up (div,prop) {
div.style[prop] = parseFloat(window.getComputedStyle(div,null)[prop]) + 10 + 'px';
}
function returnUpAndDown (div,flag) {
return function (prop) {
if(flag == 'up'){
return function () {
div.style[prop] = parseFloat(window.getComputedStyle(div,null)[prop]) + 10 + 'px';
}
}else if(flag == 'down'){
return function () {
div.style[prop] = parseFloat(window.getComputedStyle(div,null)[prop]) - 10 + 'px';
}
}else{
throw error;
}
}
}
var fatherUp = returnUpAndDown(div,'up');
var fatherDown = returnUpAndDown(div,'down');
var arr = ['width','height','fontSize','left','top'];
var newArrUp = arr.map(function (item,index) {
return fatherUp(item);
});
var newArrDown = arr.map(function (item,index) {
return fatherDown(item);
});
var ArrUpAndDown = newArrUp.concat(newArrDown);
ArrUpAndDown.forEach(function (item,index) {
buttonArray[index].onclick = function () {
item();
}
})
</script>
</body>
</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
26
27
28
29
刚开始这么想的,用debounce
var debounce = (function () {
// 让每个函数拥有同一个 timer
var timer = null;
return function (fun,delay) {
var delay = delay || 1000;
return function () {
var self = this;
var args = arguments;
timer = setTimeout(function () {
fun.apply(self,args);
},delay);
}
}
})();
... 此部分与上面相同
var newArrUp = arr.map(function (item,index) {
return debounce(fatherUp(item));
});
var newArrDown = arr.map(function (item,index) {
return debounce(fatherDown(item));
});
...此部分与上面相同
我的思路是,首先要实现延迟,自然想到debounce 防抖
要互相之间影响,所以让他们拥有同一个timer,
结果,后一个操作会取消前一个操作,
也就是说,
我们需要每次操作的时候,把不同的函数操作,放进一个函数里,然后延迟执行?
事件累积作业2.0版本
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
我们让每个button点击事件都绑定同一个函数,
每个点击事件会传一个参数,来决定要改变哪个属性.
但会有延迟.
<script type="text/javascript">
var debounce = (function () {
// 让每个函数拥有同一个 timer
var timer = null;
return function (fun,delay) {
var delay = delay || 1000;
return function () {
var self = this;
var args = arguments;
timer = setTimeout(function () {
fun.apply(self,args);
},delay);
}
}
})();
// 我希望点击,发生相应的改变
var div = document.getElementsByTagName('div')[0];
var buttonArray =[].slice.call(document.getElementsByTagName('button'));
buttonArray.forEach(function (item,index) {
item.index = index;
})
function up (div,prop) {
div.style[prop] = parseFloat(window.getComputedStyle(div,null)[prop]) + 10 + 'px';
}
function returnUpAndDown (div,flag) {
return function (prop) {
if(flag == 'up'){
return function () {
div.style[prop] = parseFloat(window.getComputedStyle(div,null)[prop]) + 10 + 'px';
}
}else if(flag == 'down'){
return function () {
div.style[prop] = parseFloat(window.getComputedStyle(div,null)[prop]) - 10 + 'px';
}
}else{
throw error;
}
}
}
var fatherUp = returnUpAndDown(div,'up');
var fatherDown = returnUpAndDown(div,'down');
var arr = ['width','height','fontSize','left','top','width','height','fontSize','left','top'];
// 有个函数,每次点击都会点击这个函数,并且传一个参数给他,要他执行哪个,
// 这个参数应该是个唯一标识.
function proxy () {
var index = this.index;
console.log(arr[index]);
if (index < 5) {
this.style[arr[index]] = fatherUp([arr[index]])();
}else{
this.style[arr[index]] = fatherDown([arr[index]])();
}
}
buttonArray.forEach(function (item,index) {
buttonArray[index].onclick = proxy;
})
// 我们希望,就跟防抖一样,有个延迟作用.
// 关键是让不同函数,拥有同一个timer?
// 最简单的是闭包
</script>
</body>
</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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
下面的这种写法,虽然实现的功能,但我看不出哪里有代理模式的意思?
下面的这种写法,给我的第一个启示是,先整理好数据,比什么都重要..
<script type="text/javascript">
// 我希望点击,发生相应的改变
var div = document.getElementsByTagName('div')[0];
var buttonArray =[].slice.call(document.getElementsByTagName('button'));
buttonArray.forEach(function (item,index) {
item.index = index;
})
// 有个函数,每次点击都会点击这个函数,并且传一个参数给他,要他执行哪个,
// 这个参数应该是个唯一标识.
var timer = null;// timer 和 obj 这两个餐宿可以放进proxy闭包里?
var obj = {
width : parseInt(window.getComputedStyle(div,null).width),
height : parseInt(window.getComputedStyle(div,null).height),
left : parseInt(window.getComputedStyle(div,null).left),
top : parseInt(window.getComputedStyle(div,null).top),
fontSize : parseInt(window.getComputedStyle(div,null).fontSize)
};
function proxy () {
var index = this.index;
var prop = arr[index];
if (index < 5) {
obj[prop] += 10;
}else{
obj[prop] -= 10;
}
clearInterval(timer);
timer = setTimeout(function () {
for(var key in obj) {
div.style[key] = obj[key] + 'px';
}
},1000);
console.log(obj);
}
buttonArray.forEach(function (item,index) {
buttonArray[index].onclick = proxy;
})
</script>
第二种思路 累积函数
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
把函数放进一个大函数里?
事件绑定在这个大函数(代理函数?)上.
每次事件触发时,
把相应的函数放进某个数组里.
重复点击,则重复放进数组里?
大函数有延时作用.
一旦超过事件,则遍历数组,执行里面的函数?
<script type="text/javascript">
// 我希望点击,发生相应的改变
var div = document.getElementsByTagName('div')[0];
var buttonArray =[].slice.call(document.getElementsByTagName('button'));
buttonArray.forEach(function (item,index) {
item.index = index;
})
// 创建10 个函数
function getStyle (prop) {
return parseInt(window.getComputedStyle(div,null)[prop]);
}
function change (prop,flag) {
if (flag == 'up') {
div.style[prop] = getStyle(prop) + 10 + 'px';
}else{
div.style[prop] = getStyle(prop) - 10 + 'px';
}
}
var proxy = (function () {
var timer = null;
var obj = {
0 : ['width','up'],
1 : ['height','up'],
2 : ['fontSize','up'],
3 : ['left','up'],
4 : ['top','up'],
5 : ['width','down'],
6 : ['height','down'],
7 : ['fontSize','down'],
8 : ['left','down'],
9 : ['top','down']
};
var arr = [];
return function () {
var index = this.index;
arr.push(function () {
change(obj[index][0],obj[index][1]);
});
clearInterval(timer);
timer = setInterval(function () {
arr.forEach(function (item,index) {
item();
});
arr = [];
},1000);
}
})();
buttonArray.forEach(function (item,index) {
item.onclick = proxy;
})
</script>
原谅我里面很多地方写得很烂,
但这里的重点是,
这里的累积是,累积了要执行的函数.
放在了一个数组里.
以前在哪里见过,终于用上一回.