裝飾者模式筆記 在不改變原對象的基礎上, 通過對其進行包裝拓展(添加屬性或方法)使原有對象可以滿足用戶的更複雜要求。 需求不是一成不變的,需求會不斷改進,以增強用戶體驗 demo實例:對輸入框添加focus與blur事件 這個實例中,輸入框只有一兩個時,新添需求不覺得麻煩,當有許多輸入框都要新添需求 ...
裝飾者模式筆記
在不改變原對象的基礎上,
通過對其進行包裝拓展(添加屬性或方法)使原有對象可以滿足用戶的更複雜要求。
需求不是一成不變的,需求會不斷改進,以增強用戶體驗
demo實例:對輸入框添加focus與blur事件
這個實例中,輸入框只有一兩個時,新添需求不覺得麻煩,當有許多輸入框都要新添需求時,實現會很麻煩,而使用裝飾者模式卻能很簡單完成
html代碼
1 <style> 2 #container{width: 800px;margin:100px auto;} 3 input{margin-right:5px;} 4 span{font-size: 12px;color:#999;} 5 </style> 6 <div id="container"> 7 <input name="uname" id="uname" value="" placeholder="請輸入用戶名"/><span id="uname_demo_text">用戶名以字母開頭,由字母、數字、下劃線組成,長度3-16位</span><span id="uname_warn_text"></span><br/><br/> 8 <input name="phone" id="phone" value="" placeholder="請輸入手機號碼"/><span id="phone_demo_text">手機號碼以13、14、15、18開頭,由數字組成,長度11位</span><span id="phone_warn_text"></span> 9 </div>
原有事件功能
1 var uname=document.getElementById("uname"); 2 var phone=document.getElementById("phone"); 3 var unameDemoText=document.getElementById("uname_demo_text"); 4 var unameWarnText=document.getElementById("uname_warn_text"); 5 var phoneDemoText=document.getElementById("phone_demo_text"); 6 var phoneWarnText=document.getElementById("phone_warn_text"); 7 uname.onblur = function(){ 8 var nameValid=/^[a-zA-Z][a-zA-Z0-9_]{5,17}$/i; 9 if(!nameValid.test(uname.value)){ 10 unameWarnText.innerHTML="用戶名不符合填寫規則"; 11 }else{ 12 unameWarnText.innerHTML="用戶名符合填寫規則"; 13 } 14 } 15 phone.onblur = function(){ 16 var phoneValid=/^1(3|4|5|8)\d{9}$/i; 17 if(!phoneValid.test(phone.value)){ 18 phoneWarnText.innerHTML="手機號碼不符合填寫規則"; 19 }else{ 20 phoneWarnText.innerHTML="手機號碼符合填寫規則"; 21 } 22 }
裝飾者
1 /*裝飾者*/ 2 var decorator=function(input,focusFn,blurFn){ 3 //獲取事件源 4 var input=document.getElementById(input); 5 //判斷事件源是否綁定focus事件 6 if(typeof input.onfocus === 'function'){ 7 //緩存事件源原有回調函數 8 var oldFocusFn = input.onfocus; 9 //為事件源定義新的事件 10 input.onfocus = function(){ 11 //事件源原有回調函數 12 oldFocusFn(); 13 //新增回調函數 14 focusFn(); 15 } 16 }else{ 17 //事件源未綁定事件,直接為事件源添加新增回調函數 18 input.onfocus = focusFn; 19 } 20 //判斷事件源是否綁定blur事件 21 if(typeof input.onblur === 'function'){ 22 //緩存事件源原有回調函數 23 var oldBlurFn = input.onblur; 24 //為事件源定義新的事件 25 input.onblur = function(){ 26 oldBlurFn(); 27 blurFn(); 28 } 29 }else{ 30 //事件源未綁定事件,直接為事件源添加新增回調函數 31 input.onblur = blurFn; 32 } 33 }
新增回調函數
1 decorator('uname',function(){ 2 //新增focus回調函數 3 unameDemoText.style.display="none"; 4 },function(){ 5 //新增blur回調函數 6 unameWarnText.style.color="#f03"; 7 }); 8 decorator('phone',function(){ 9 //新增focus回調函數 10 phoneDemoText.style.display="none"; 11 },function(){ 12 //新增blur回調函數 13 phoneWarnText.style.color="#f03"; 14 });
代碼測試:
優化裝飾者方法
/*優化裝飾者方法*/ var decorator = function(id,type,fn){ var dom = typeof id === 'string' ? document.getElementById(id) : id; //判斷事件源是否綁定事件 if(typeof dom[type] === 'function'){ //緩存事件源原有回調函數 var oldFn = dom[type]; //為事件源定義新的事件 dom[type] = function(){ //事件源原有回調函數 oldFn(); //新增回調函數 fn(); } }else{ //事件源未綁定事件,直接為事件源添加新增回調函數 dom[type] = fn; } };
調用裝飾者方法
1 decorator('uname','onfocus',function(){ 2 //新增focus回調函數 3 unameDemoText.style.display="none"; 4 }); 5 decorator('uname','onblur',function(){ 6 //新增focus回調函數 7 unameWarnText.style.color="#f03"; 8 }); 9 decorator('phone','onfocus',function(){ 10 //新增focus回調函數 11 phoneDemoText.style.display="none"; 12 }); 13 decorator('phone','onblur',function(){ 14 //新增focus回調函數 15 phoneWarnText.style.color="#f03"; 16 });
瀏覽器顯示效果同上