1 事件庫的復習及最終版封裝
- 依賴的庫:不依賴任何庫;
- 使用方法:
- 為全局函數(shù)調(diào)用亩钟;
- 系統(tǒng)行為事件綁定:on(ele,type,fn);解除綁定:off(ele,type,fn)
- 綁定及執(zhí)行結(jié)果:所有瀏覽器兼容,但事件觸發(fā)時曹步,fn中this為ele,即元素休讳,默認傳入一個事件對象實參
- 自定義行為事件綁定:on(ele,type,fn);執(zhí)行:fire.call(ele,type,e);解綁:off(ele,type,fn)讲婚;
- 綁定時on中的ele為元素,fire函數(shù)在調(diào)用時必須保證里面的this為元素俊柔;type自定義行為的開頭必須以my開頭筹麸;
- 綁定及執(zhí)行結(jié)果:fire作為接口放在函數(shù)中執(zhí)行,如果未用on綁定方法雏婶,里面無執(zhí)行函數(shù)物赶;當用on綁定方法后,就會在預留接口處執(zhí)行方法留晚;用于訂閱發(fā)布酵紫;執(zhí)行的函數(shù)中的this為當前元素;
- 改變函數(shù)的this執(zhí)行:processThis(fn,thisArg)即:將fn中的this指向改變?yōu)閠hisArg
- 執(zhí)行結(jié)果:將fn中的this指向改變?yōu)閠hisArg错维,并給fn傳一個實參e,一般跟事件配合奖地,返回一個匿名函數(shù);
- 注意:
- 綁定自定義行為事件時赋焕,on里面的參數(shù)ele可以是元素也可以是實例對象参歹,但事件庫主要用于給元素綁定系統(tǒng)行為或自定義行為,所以參數(shù)ele為元素隆判;一般不設置實例對象犬庇;
- 代碼:
- 執(zhí)行代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件庫最終版封裝</title> <style> body{ height: 1000px; } div{ width: 200px; height: 200px; background-color: red; } </style> </head> <body> <div id="div1">111</div> <script src="復習JS庫/01Event.js"></script> <script> var oDiv=document.getElementById("div1"); on(oDiv,"mymeinv",fn1); on(oDiv,"mymeinv",fn2); on(oDiv,"mymeinv",fn3); //off(oDiv,"mymeinv",fn3); function fn1(e) { console.log(this.innerHTML); console.log(e.pageY); } function fn2() { console.log(2); } function fn3() { console.log(3); } on(oDiv,"click",fn4); function fn4(e){ fire.call(this,"mymeinv",e); } //processThis函數(shù)驗證 function add(e) { console.log(this); console.log(e.type); } on(oDiv,"click",processThis(add,oDiv)); </script> </body> </html>
- 事件庫終極版封裝
function on(ele,type,fn) { if(/^my/gi.test(type)){//綁定的是自定義行為,必須以my開頭 //事件庫中ele均為元素 if(!ele[type]){ ele[type]=[]; } var b=ele[type]; if(b.length){ for(var i=0; i<b.length; i++){ if(b[i]===fn) return; } } b.push(fn); }else{//綁定的是系統(tǒng)行為侨嘀,如click,mousemove等 //瀏覽器的兼容 if(ele.addEventListener){ ele.addEventListener(type,fn,false); }else{//IE瀏覽器 if(!ele["on"+type]){ ele["on"+type]=[]; //將run方法綁定到系統(tǒng)事件池中 ele.attachEvent("on"+type,function (e) { run.call(ele,e);//保證run中的this指向為當前元素臭挽;在IE瀏覽器下事件觸發(fā),不會給匿名函數(shù)傳事件對象實參咬腕; }) } var a=ele["on"+type]; //去重處理欢峰,避免重復綁定 if(a.length){ for(var i=0; i<a.length; i++){ if(a[i]===fn) return; } } a.push(fn); } } } //fire函數(shù)相當于一個接口,在某個位置執(zhí)行on綁定的type行為上的所有方法; function fire(type,e) { //fire中的this可以指元素赤赊,也可以指實例對象,與on中相對應煞赢; var b=this[type] || []; if(b.length){ for(var i=0; i<b.length; i++){ if(typeof b[i]==="function"){ b[i].call(this,e);//保證函數(shù)執(zhí)行時抛计,里面的this為當前this,即為元素照筑,并傳入實參e; }else{ b.splice(i,1); i--; } } } } function run(e) { e= e || window.event; //e的兼容處理 e.target=e.srcElement; e.pageX=(document.documentElement.scrollLeft || document.body.scrollLeft)+e.clientX; e.pageY=(document.documentElement.scrollTop || document.body.scrollTop)+e.clientY; //阻止默認事件 e.preventDefault=function () { e.returnValue=false; }; //阻止冒泡 e.stopPropagation=function () { e.cancelBubble=true; }; //遍歷run執(zhí)行函數(shù)吹截,保證函數(shù)中的this為當前元素,而且給其傳實參e var a=this["on"+e.type];//this為當前元素 if(a.length){ for(var i=0; i<a.length; i++){ if(typeof a[i]==="function"){ a[i].call(this,e); }else{ a.splice(i,1); i--;//防止數(shù)組塌陷 } } } } function off(ele,type,fn) { if(/^my/gi.test(type)){ var b=ele[type]; if(b.length){ for(var i=0; i<b.length; i++){ if(b[i]===fn){ b[i]=null; break; } } } }else{ if(ele.removeEventListener){ ele.removeEventListener(type,fn,false); }else{ var a=ele["on"+type]; if(a.length){ for(var i=0; i<a.length; i++){ if(a[i]===fn){ a[i]=null; break;//性能優(yōu)化凝危; } } } } } } //改變函數(shù)的this執(zhí)行 function processThis(fn,thisArg) { return function (e) { fn.call(thisArg,e); } }
2 運動庫的復習及最終版封裝
- 依賴的庫:依賴utils庫波俄,用于接口使用時,依賴Event事件庫蛾默;
- 使用方法:
- 代碼:
animate(opt)
;為全局函數(shù)調(diào)用懦铺; - 參數(shù):對象opt
- 必須傳的參數(shù):1)ele:元素,指需要運動的元素支鸡;2)target:屬性值為對象冬念,對象中的鍵值對為目標值;
- 可傳可不傳的參數(shù):1)duration:運動總時間牧挣,默認為2000ms急前;2)effect:運動方式,可以是字符串瀑构,也可以是數(shù)字裆针,默認為Linear線性運動;3)callback:不傳不執(zhí)行寺晌,傳了之后執(zhí)行函數(shù)世吨,函數(shù)中this被設置為元素;
- 代碼:
- 注意點:在運動結(jié)束后折剃,設置一個fire接口另假,接口的類型為myAnimate,若需要執(zhí)行操作怕犁,可用on在元素身上綁定該行為的方法边篮;fire接口中設置的this為該元素,即綁定的方法執(zhí)行時奏甫,函數(shù)中的this為該元素戈轿;
- 執(zhí)行結(jié)果:
- 目的:一個元素從開始位置(ele)在規(guī)定時間(duration)內(nèi),以什么樣的運動形式(effect)阵子,到達指定目的地(target)思杯,執(zhí)行什么動作(callback或fire接口執(zhí)行);
- 代碼:
- 執(zhí)行代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>運動庫驗證</title> <style> *{ margin: 0; padding: 0; } #div1{ width: 80px; height: 80px; background-color: red; line-height: 80px; text-align: center; position: absolute; top: 10px; left:200px; opacity: 0.1; filter: alpha(opacity=10); } #div2{ width: 1px; height: 500px; margin-top: 10px; background-color: blue; position: absolute; top: 10px; left: 1100px; } </style> </head> <body> <div id="div1">物體</div> <div id="div2"></div> <script src="復習JS庫/00utils.js"></script> <script src="復習JS庫/01Event.js"></script> <script src="復習JS庫/02Animate.js"></script> <script> var oDiv1=document.getElementById("div1"); function fn1(){ //此時函數(shù)中的this為元素; console.log(this.innerHTML); this.style.border="5px solid pink"; this.innerHTML="我成功了色乾,祝賀我吧誊册!"; this.style.fontSize="10px"; this.style.lineHeight="10px"; } //綁定myAnimate行為,執(zhí)行方法 on(oDiv1,"myAnimate",fn1); animate({ ele:oDiv1, target:{ left:1000, top:400, opacity: 0.8 }, effect:6, duration: 2000 //此時callback可以不用暖璧,可以用預留的接口案怯,然后進行綁定執(zhí)行; /*callback:function () { //默認情況下回調(diào)函數(shù)執(zhí)行時澎办,this指向window; //在調(diào)用時嘲碱,用call改變this指向為ele; this.style.backgroundColor="yellow"; }*/ }) </script> </body> </html>
- 封裝代碼:
(function () { //運動形式對象 var gbEffect= { Linear: function (t, b, c, d){ //勻速 return c*t/d + b; }, EaseIn: function(t, b, c, d){ //加速曲線 return c*(t/=d)*t + b; }, EaseOut: function(t, b, c, d){ //減速曲線 return -c *(t/=d)*(t-2) + b; }, EaseBoth: function(t, b, c, d){ //加速減速曲線 if ((t/=d/2) < 1) { return c/2*t*t + b; } return -c/2 * ((--t)*(t-2) - 1) + b; }, EaseInStrong: function(t, b, c, d){ //加加速曲線 return c*(t/=d)*t*t*t + b; }, EaseOutStrong: function(t, b, c, d){ //減減速曲線 return -c * ((t=t/d-1)*t*t*t - 1) + b; }, EaseBothStrong: function(t, b, c, d){ //加加速減減速曲線 if ((t/=d/2) < 1) { return c/2*t*t*t*t + b; } return -c/2 * ((t-=2)*t*t*t - 2) + b; }, Elastic:{ In: function(t, b, c, d, a, p){ //正弦衰減曲線(彈動漸入) if (t === 0) { return b; } if ( (t /= d) == 1 ) { return b+c; } if (!p) { p=d*0.3; } if (!a || a < Math.abs(c)) { a = c; var s = p/4; } else { var s = p/(2*Math.PI) * Math.asin (c/a); } return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; }, Out: function(t, b, c, d, a, p){ //正弦增強曲線(彈動漸出) if (t === 0) { return b; } if ( (t /= d) == 1 ) { return b+c; } if (!p) { p=d*0.3; } if (!a || a < Math.abs(c)) { a = c; var s = p / 4; } else { var s = p/(2*Math.PI) * Math.asin (c/a); } return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; }, Both: function(t, b, c, d, a, p){ if (t === 0) { return b; } if ( (t /= d/2) == 2 ) { return b+c; } if (!p) { p = d*(0.3*1.5); } if ( !a || a < Math.abs(c) ) { a = c; var s = p/4; } else { var s = p/(2*Math.PI) * Math.asin (c/a); } if (t < 1) { return - 0.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; } return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*0.5 + c + b; } }, Back:{ In: function(t, b, c, d, s){ //回退加速(回退漸入) if (typeof s == 'undefined') { s = 1.70158; } return c*(t/=d)*t*((s+1)*t - s) + b; }, Out: function(t, b, c, d, s){ if (typeof s == 'undefined') { s = 3.70158; //回縮的距離 } return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; }, Both: function(t, b, c, d, s){ if (typeof s == 'undefined') { s = 1.70158; } if ((t /= d/2 ) < 1) { return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; } return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; } }, Bounce:{ In: function(t, b, c, d){ //彈球減振(彈球漸出) return c - gbEffect.Bounce.Out(d-t, 0, c, d) + b; }, Out: function(t, b, c, d){ if ((t/=d) < (1/2.75)) { return c*(7.5625*t*t) + b; } else if (t < (2/2.75)) { return c*(7.5625*(t-=(1.5/2.75))*t + 0.75) + b; } else if (t < (2.5/2.75)) { return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b; } return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b; }, Both: function(t, b, c, d){ if (t < d/2) { return gbEffect.Bounce.In(t*2, 0, c, d) * 0.5 + b; } return gbEffect.Bounce.Out(t*2-d, 0, c, d) * 0.5 + c*0.5 + b; } } }; var gbEffectAry=["Linear","EaseIn","EaseOut","EaseBoth","EaseInStrong","EaseOutStrong","EaseBothStrong","Elastic-In","Elastic-Out","Elastic-Both","Back-In","Back-Out","Back-Both","Bounce-In","Bounce-Out","Bounce-Both"]; //運動庫封裝 function animate(opt) { //0 對傳入的實參值進行判斷局蚀; opt=opt || {}; if(!opt.ele) return;//如果傳參錯誤麦锯,代碼阻斷不執(zhí)行; //1 新建一個對象琅绅,里面添加默認樣式 var defaultOpt={ duration: 2000, effect: "Linear" }; //2 將傳入的實參opt扶欣,所有屬性賦值給defaultOpt,如果存在千扶,則重新賦值宵蛀,如果不存在,使用默認值县貌; for(var attr in opt){ defaultOpt[attr]=opt[attr]; } //總結(jié):defaultOpt的作用是設置默認的屬性术陶,如果傳入的實參里面設置了defaultOpt里面的屬性,就重新賦值煤痕,如果沒有設置梧宫,就用默認值; //下面所有代碼不再使用opt摆碉,而使用defaultOpt; //3 獲取defaultOpt里面的參數(shù) var ele=defaultOpt.ele; var target=defaultOpt.target; var duration=defaultOpt.duration; var callback=defaultOpt.callback; var effect=defaultOpt.effect; var tempEffect=null; //4 獲取運動形式塘匣,計算參數(shù) //4.1 獲取運動形式:判斷effect的數(shù)據(jù)類型,滿足下面兩種情況巷帝,就執(zhí)行各自的代碼忌卤,如果不滿足,就使用默認值楞泼; var ary=gbEffectAry; if(typeof effect==="number"){ ary=ary[effect%ary.length].split("-"); tempEffect=ary.length>=2?gbEffect[ary[0]][ary[1]]:gbEffect[ary[0]]; }else if(typeof effect==="object"){ tempEffect=effect.length>=2?gbEffect[effect[0]][effect[1]]:gbEffect[effect[0]]; }else if(typeof effect==="string"){ tempEffect=gbEffect[effect];//此時tempEffect設置一個函數(shù)定義地址驰徊,不是函數(shù)名; } //4.2 計算傳入運動形式中的參數(shù) var begin={},change={}; for(var attr in target){ begin[attr]=utils.css(ele,attr); change[attr]=target[attr]-begin[attr]; } var time=0; //5 添加定時器 var timer=setInterval(function () { //5.1 變量累加 time+=30; //5.2 邊界值判斷 if(time>=duration){ //5.2.1 設置邊界值 utils.css(ele,target); //5.2.2 停止定時器 clearInterval(timer); //5.2.3 執(zhí)行回調(diào)函數(shù)堕阔,進行下一步操作 callback && callback.call(ele);//當callback存在的時候棍厂,執(zhí)行回調(diào)函數(shù),改變其中的this指向為元素超陆; //增加接口牺弹,用于綁定多個操作,執(zhí)行函數(shù),如果不綁定就不會執(zhí)行方法张漂; fire.call(ele,"myAnimate"); //5.2.4 阻斷程序執(zhí)行 return; } //5.3 獲取最新位置及設置最新位置 for(var attr in change){ //5.3.1 運動方式獲取最新位置晶默; var cur=tempEffect(time,begin[attr],change[attr],duration); //5.3.2 分別設置最新位置 utils.css(ele,attr,cur); } },30) } window.animate=animate;//將私有函數(shù)設置為全局變量; })();
3 ajax庫的復習及最終版封裝
- 依賴的庫:不依賴任何庫航攒;
- 使用方法:
- 代碼:
03myAjax(opt)
;為全局函數(shù)調(diào)用荤胁; - 參數(shù):對象opt
- data:對象,里面的鍵值對為搜索參數(shù)屎债;
- type:get/post/jsonp;
- get垢油、post用于本地數(shù)據(jù)獲取盆驹,不能跨域獲取滩愁;
- jsonp用于跨域獲取躯喇,需注意的是在百度服務器中必須設置jsonp參數(shù)為cb才能獲取數(shù)據(jù);
- 代碼:
- 代碼:
- 執(zhí)行代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>封裝的ajax</title> </head> <body> <script src="JS庫終極版/03myAjax.jsjs"></script> <script> 03myAjax({ url:"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su", data:{wd:"zhouxingchi"}, type:"jsonp", dataType:"json", jsonp:"cb",//此處必須設置jsonp為cb硝枉,才能使用 success:function (data) { console.log(data); } }); </script> </body> </html>
- JS庫封裝代碼:
//參數(shù):ajax({url:xxx,data:xxx,type:xxx,dataType:xxx,jsonp:xxx,fnLoading:xxx,complete:xxx,success:xxx,error:xxx,timeout}) //將對象中的屬性名和屬性值轉(zhuǎn)化為key=val&key=val的形式 function json2url(obj) { //參數(shù):對象廉丽,返回值:字符串 //思路:對象-數(shù)組-字符串 obj.t=Math.random();//避免緩存 var ary=[]; //遍歷對象 for(var attr in obj){ ary.push(attr+"="+obj[attr]); } return ary.join("&"); } function jsonParse(strJson) { return "JSON" in window?JSON.parse(strJson):eval("("+strJson+")"); } function 03myAjax(json) { json=json||{}; //如果json中請求地址url不存在 if(!json.url) return; //參數(shù)獲取 var url=json.url; //data屬性值為一個對象,對象中為參數(shù) var data=json.data||{}; var type=json.type||"get"; var jsonp=json.jsonp||"callback"; var timeout=json.timeout||3000; var timer=null; //四步: //1 創(chuàng)建一個xml對象 //每個類函數(shù)都是window的一個屬性妻味; if(window.XMLHttpRequest){ var xml=new XMLHttpRequest(); }else{//IE6兼容處理 var xml=new ActiveXObject("Microsoft.XMLHTTP"); } //2 打開地址正压;3 發(fā)送請求 //get請求:參數(shù)在地址中,在url?的后面责球,以鍵值對的形式連接焦履; //post請求:參數(shù)在請求體中,地址url后面不跟參數(shù)雏逾; switch(type.toLowerCase()){ case "get": xml.open("get",url+"?"+json2url(data),true); xml.send(null); break; case "post": xml.open("post",url,true); xml.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xml.send(json2url(data)); break; case "jsonp": //新建一個全局函數(shù) var kbfd="jsonp_"+Math.random(); kbfd=kbfd.replace(".","");//函數(shù)名中不能存在小數(shù)點嘉裤,所以需要替換 window[kbfd]=function (data) { json.success && json.success(data); //卸磨殺驢,干掉script document.body.removeChild(oS); oS=null; }; data[jsonp]=kbfd; //創(chuàng)建script標簽栖博,設置其src屑宠,通過script發(fā)送請求 var oS=document.createElement("script"); //script中src包含url?參數(shù)&cb=kbfd oS.src=url+"?"+json2url(data); //script必須插入到頁面的底部 document.body.appendChild(oS); break; } //響應請求之前的準備 json.fnLoading && json.fnLoading(); //4 響應請求 xml.onreadystatechange=function () { if(xml.readyState===4){ //請求成功 json.complete && json.complete(); clearTimeout(timer); //判斷后臺響應成功還是失敗仇让; if(/^2\d{2}$/.test(xml.status)){//響應成功 if(json.dataType==="json"){ json.success && json.success(jsonParse(xml.responseText)); }else{ json.success && json.success(xml.responseText); } }else{//響應失敗 json.error && json.error(xml.status); } } }; if(type==="jsonp") return; //5 等待超時 timer=setTimeout(function () { alert("您的網(wǎng)絡不行啊"); xml.onreadystatechange=null; },timeout); }
4 拖拽庫復習及最終版封裝
- 依賴的庫:Event事件庫
- 使用方法:
- 代碼:
var res=new Drag(opt)
;為實例創(chuàng)建調(diào)用典奉; - 參數(shù):對象opt;
- ele:必須穿,為拖拽元素丧叽;
- 執(zhí)行結(jié)果:元素純凈版拖拽秋柄,無邊界值判斷,可拖拽到任何地方蠢正;
- 代碼:
- 擴展功能:
- 預留接口:給實例對象綁定了三個自定義行為:myDragDown myDragMove myDragUp
- 在鼠標按下事件中骇笔,添加自定義行為myDragDown
- 在鼠標移動事件中,添加自定義行為myDragMove
- 在鼠標抬起事件中,添加自定義行為myDragUp
- 綁定代碼:
res.on("myDragDown",fn1).on("myDragMove",fn2).on("myDragUp",fn3).off("myDragUp",fn3)
笨触,鏈式操作綁定懦傍; - 執(zhí)行結(jié)果:綁定的方法函數(shù)fn1,fn2等,函數(shù)中的this為實例對象芦劣,并傳入事件對象e;
- 預留接口:給實例對象綁定了三個自定義行為:myDragDown myDragMove myDragUp
- 代碼:
- 執(zhí)行代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>拖拽Drag庫封裝驗證</title> <style> div{ width: 200px; height: 200px; background-color: red; position: absolute; left: 0; top: 0; } </style> </head> <body> <div id="div">111</div> <script src="JS庫終極版/01Event.js"></script> <script src="JS庫終極版/04Drag.js"></script> <script> var oDiv=document.getElementById("div"); var res=new Drag({ ele:oDiv }); res.on("myDragDown",fn1).on("myDragMove",fn2).on("myDragUp",fn3).off("myDragUp",fn3);//鏈式操作 function fn1() { console.log(this);//this為實例 console.log(1) } function fn2() { console.log(2) } function fn3() { console.log(3) } </script> </body> </html>
- JS封裝代碼:
//EventEmitter類:給實例對象的自定義行為綁定多個方法粗俱,訂閱發(fā)布執(zhí)行 function EventEmitter() {} EventEmitter.prototype.on=function (type,fn) { if(!this[type]){ this[type]=[]; } var a=this[type]; if(a.length){ for(var i=0; i<a.length; i++){ if(a[i]===fn) return; } } a.push(fn); return this;//進行鏈式操作 }; EventEmitter.prototype.fire=function(type,e){ //保證fire函數(shù)執(zhí)行時,里面的this為實例對象虚吟; var a=this[type] || []; if(a.length){ for(var i=0; i<a.length; i++){ if(typeof a[i]==="function"){ a[i].call(this,e);//保證函數(shù)執(zhí)行時寸认,里面的this為實例對象,并傳事件對象實參串慰; }else{ a.splice(i,1); i--; } } } }; EventEmitter.prototype.off=function (type,fn) { var a=this[type]; if(a.length){ for(var i=0; i<a.length; i++){ if(a[i]===fn){ a[i]=null; break; } } } }; //Drag類:拖拽 function Drag(opt) { opt=opt||{}; if(!opt.ele) return; this.ele=opt.ele; this.disX=null; this.disY=null; this.DOWN=null; this.MOVE=null; this.UP=null; this.init(); } //原型鏈繼承 Drag.prototype=new EventEmitter(); //原型鏈繼承后偏塞,原型上沒有自己類的constructor屬性,需要重新設置 Drag.prototype.constructor=Drag; //原型上公共方法 Drag.prototype.init=function () { //綁定down事件邦鲫; this.DOWN=processThis(this.down,this); on(this.ele,"mousedown",this.DOWN); }; Drag.prototype.down=function (e) { //獲取鼠標相對于元素的位置disX,disY this.disX=e.clientX-this.ele.offsetLeft; this.disY=e.clientY-this.ele.offsetTop; //綁定move,up事件 this.MOVE=processThis(this.move,this); this.UP=processThis(this.up,this); if(this.ele.setCapture){//IE瀏覽器 this.ele.setCapture();//焦點捕獲 on(this.ele,"mousemove",this.MOVE); on(this.ele,"mouseup",this.UP); }else{//標準瀏覽器 //將事件綁定到document上灸叼,阻止默認事件發(fā)生; on(document,"mousemove",this.MOVE); on(document,"mouseup",this.UP); e.preventDefault(); } this.fire("myDragDown",e);//添加接口庆捺,實例對象調(diào)用fire公共方法古今,自定義行為是myDragDown }; Drag.prototype.move=function (e) { //獲取新位置,無邊界值判斷 var l=e.clientX-this.disX; var t=e.clientY-this.disY; //設置新位置 this.ele.style.left=l+"px"; this.ele.style.top=t+"px"; this.fire("myDragMove",e);//添加接口滔以,實例對象調(diào)用fire公共方法捉腥,自定義行為是myDragMove }; Drag.prototype.up=function (e) { if(this.ele.releaseCapture){ this.ele.releaseCapture();//釋放焦點捕獲; off(this.ele,"mousemove",this.MOVE); off(this.ele,"mouseup",this.UP); }else{ off(document,"mousemove",this.MOVE); off(document,"mouseup",this.UP); } this.fire("myDragUp",e);//添加接口你画,實例對象調(diào)用fire公共方法但狭,自定義行為是myDragUp };
5 myBind函數(shù)封裝
- 依賴的庫:不依賴任何庫
- 使用方法:
- 代碼:
fn1.myBind(oDiv,2,3)
; - 調(diào)用:函數(shù)名調(diào)用撬即,myBind為函數(shù)類原型上的方法立磁,所有函數(shù)均能調(diào)用;
- 參數(shù):
- 第一個參數(shù):thisArg剥槐,必須傳唱歧,用于改變函數(shù)的this指向,不改變賦值null;
- 第二個參數(shù):實參粒竖,可傳可不傳颅崩,如果需要實參則傳,不需要則不傳蕊苗;
- 默認傳入一個事件對象實參沿后;多與事件配合;
- 返回值為一個匿名函數(shù)朽砰,即函數(shù)的預處理尖滚;
- 執(zhí)行結(jié)果:改變fn1函數(shù)中的this指向為thisArg喉刘,給fn1傳實參,與事件對象配合默認傳入一個事件對象實參漆弄;返回一個匿名函數(shù)睦裳;
- 代碼:
- 代碼:
- 執(zhí)行代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>myBind函數(shù)封裝驗證</title> <style> div{ width: 200px; height: 200px; background-color: red; } </style> </head> <body> <div id="div1">1111</div> <script src="JS庫終極版/05myBind.js"></script> <script> var oDiv=document.getElementById("div1"); function fn1(n,m,e){ console.log(this.innerHTML); console.log(n+m); console.log(e.pageX); } oDiv.onclick=fn1.myBind(oDiv,2,3); </script> </body> </html>
- JS封裝代碼:
(function () { Function.prototype.myBind=function (thisArg) { var outArg=[].slice.call(arguments,1); if("bind" in Function.prototype){ return this.bind.apply(this,[thisArg].concat(outArg)); } var _this=this; return function (e) { e=arguments.length===0?window.event:e; //IE瀏覽器下的兼容處理 e.target=e.srcElement; e.pageX=(document.documentElement.scrollLeft ||document.body.scrollLeft)+e.clientX; e.pageY=(document.documentElement.scrollTop || document.body.scrollTop)+e.clientY; //阻止默認事件 e.preventDefault=function () { e.returnValue=false; }; //阻止冒泡 e.stopPropagation=function () { e.cancelBubble=true; }; return _this.apply(thisArg,outArg.concat(e)); } }; })();