装饰者模式:在不改变原对象的基础上,通过对其进行包装拓展 (添加属性或者方法)使原有对象可以满足用户的更复杂需求。
1 <body>
2 用户:<input id="user" type="text" value='user' />
3 密码:<input id='password' type="password" value="121212"/><br/>
4 <div class='parent'>
5 <div class='fixed'>高度固定</div>
6 <div class='fill'>填满剩下的高度</div>
7 </div>
8 <script type="text/javascript">
9 // 装饰者:不改变原有对象的基础上,通过对其进行包装拓展(添加方法或者属性)使原有对象可以满足用户更复杂的需求
10 // 比如绑定focus事件
11 function addEvent(dom, type, fn) {
12 // 对于支持DOM2级事件处理程序addEventListener方法的浏览器
13 if(dom.addEventListener) {
14 dom.addEventListener(type, fn, false);
15
16 }
17 // 对于不支持addEventListener方法但支持attachEvent方法的浏览器
18 else if(dom.attachEvent){
19 dom.attachEvent('on' + 'type', fn);
20 }
21 // 对于不支持addEventListener方法也不支持attachEvent方法,但支持on+'事件名'的浏览器
22 else {
23 dom['on' + type] = fn;
24 }
25 }
26 // 获取事件对象
27 var getEvent = function(event) {
28 // 标准浏览器返回event,IE下window.event
29 return event || window.event;
30 }
31 // 获取元素
32 var getTarget = function(event) {
33 var event = getEvent(event);
34 // 标准浏览器下event.target,IE下event.srcElement
35 return event.target || event.srcElement;
36 }
37 var user = document.getElementById('user');
38 var password = document.getElementById('password');
39 addEvent(user, 'focus' , function(){
40 console.log("首次绑定focus")
41 });
42 addEvent(password, 'focus' , function(){
43 console.log("首次绑定focus")
44 });
45
46 // 装饰者
47 var decorator = function(input, fn) {
48 // 获取事件源
49 var input = document.getElementById(input);
50 // 若事件源已经绑定事件
51 if(typeof input.onfocus === 'function') {
52 // 缓存事件源原有回调函数
53 var oldClickFn = input.onfocus;
54 // 为事件源定义新的事件
55 input.onfocus = function() {
56 // 事件源定义新的事件
57 oldClickFn();
58 // 执行事件源新增的回调函数
59 fn();
60 }
61 }else {
62 // 事件源未绑定事件,直接为事件源添加新增回调函数
63 input.onfocus = fn;
64 }
65 // 做其他事件
66 }
67
68 // 举例
69 decorator('user', function() {
70 console.log('2')
71 })
72 decorator('password', function() {
73 console.log('3')
74 })
75 </script>
76 </body>