1. 程式人生 > 其它 >彈窗外掛封裝 js外掛封裝-彈窗元件封裝-型別判斷-釋出訂閱

彈窗外掛封裝 js外掛封裝-彈窗元件封裝-型別判斷-釋出訂閱

https://gitee.com/eric167/js---

<!DOCTYPEhtml> <htmllang="en"> <head> <metacharset="UTF-8"> <metahttp-equiv="X-UA-Compatible"content="IE=edge"> <metaname="viewport"content="width=device-width,initial-scale=1.0"> <title>Document</title> <linkrel="stylesheet"href="css/reset.min.css"> <linkrel="stylesheet"href="css/modalplugin.css"> <style> .box.form{ height:40px; display:flex; justify-content:flex-start; align-items:center; }
.box.formspan{ margin-right:3%; width:30%; text-align:right; }
.box.forminput{ width:100%; padding:05px; height:30px; box-sizing:border-box; border:1pxsolid#eee; } </style> </head> <body> <!--<divclass="drag_modal"></div> <divclass="drag_content"> <divclass="drag_head"> 系統溫馨提示 <ahref="javascript:;"class="drag_close"></a> </div> <divclass="drag_main"> 哈哈哈 </div> <divclass="drag_foot"> <ahref="javascript:;"class="drag_button">取消</a> <ahref="javascript:;"class="drag_button">確定</a> </div> </div>-->
<buttonid="btn">點我</button> <scriptsrc="./webpack/dist/modalplugin.min.js"></script>
<script> console.log(window); btn.onclick=function(){ //letm1=M({ //drag:true,//是否開啟拖拽預設開啟 //title:"登入", //template:`<divclass="box"> //<divclass="form"> //<span>使用者名稱:</span> //<inputtype="text"id="username"/> //</div> //<divclass="form"> //<span>密碼:</span> //<inputtype="password"id="password"/> //</div> //</div>`, //buttons:[ //{ //text:'取消', //click(self){ //console.log(self); //self.close(); //} //},{ //text:'確定', //click(self){ //letusername=document.querySelector('#username'), //password=document.querySelector('#password'); //console.log(username.value,password.value); //self.close(); //} //} //] //})

letm2=M({ template:"實現了外掛元件封裝", title:"提示", buttons:[ { text:'確定', click(self){ self.close(); } } ], //周期函式[回撥函式,使用者需要處理的事情都要寫在兩個回撥函式當中] onopen:self=>{ console.log('已開啟',self); }, onclose(){ console.log('已關閉',this); } })
//周期函式釋出訂閱,可以靈活的給某一個事件訂閱自己要執行的方法 m2.ondragstart.on(self=>{ console.log('拖拽開始'); }) m2.ondraging.on(self=>{ console.log('拖拽中'); }) m2.ondragend.on(self=>{ console.log('拖拽結束'); }) } </script> </body> </html> ------------------------------ /* *外掛支援的配置資訊(基於不同的配置資訊,實現不同的功能): *+title[string]標題 *+template[string]自定義的內容或者模板(基於ES6的模板字串,拼接更豐富的內容結構) *+buttons[array]自定義按鈕(組) *[{text:'確定',click:[callback]},...] *+modal[boolean]控制遮罩層是否顯示預設是true *+drag[boolean]是否允許拖拽預設是true *+onopen[function]開啟 *+onclose[function]關閉 *拖拽的生命週期函式「當前操作的某個節點上,允許使用者自定義處理的事情」 *「釋出訂閱」 *+拖拽開始ondragstart *+拖拽中ondraging *+拖拽結束ondragend * *//釋出訂閱 *//工具庫 */
importutilsfrom'./lib/utils'; importSubfrom'./lib/sub';

//外掛的核心 functionModalPlugin(config){
letself=this; self.config=config; self.$drag_modal=null; self.$drag_content=null;
self.startX=0; self.startY=0;
self.startL=0; self.startT=0;
self._MOVE=null; self._UP=null;
//如果開啟拖拽那就需要建立三個事件池 if(self.config.drag){ self.ondragstart=newSub; self.ondraging=newSub; self.ondragend=newSub; } self.init(); }
ModalPlugin.prototype={ version:'1.0.0', constructor:ModalPlugin, init(){ letself=this; self.create();
//基於事件委託實現容器中元素點選處理的相關事務關閉按鈕&&自定義按鈕 if(self.$drag_content){ self.$drag_content.addEventListener('click',function(ev){ lettarget=ev.target, targetTag=target.tagName, targetClass=target.className; //關閉按鈕 if(targetTag==='A'&&targetClass==='drag_close'){ self.close(); return; } //自定義按鈕 if(targetTag==='A'&&targetClass==='drag_button'){ letindex=+target.getAttribute('index'), item=self.config.buttons[index]; //判斷不為空並且是函式就執行函式 if(item&&utils.isFunction(item.click)){ item.click.call(self,self); } return; }
}) }
if(self.config.drag){ //開啟拖拽 let$drag_head=self.$drag_content.querySelector('.drag_head'); $drag_head.style.cursor='move'; $drag_head.addEventListener('mousedown',self.down.bind(self)); } }, //動態建立結構 create(){ letself=this, config=self.config, fragment=document.createDocumentFragment(); //建立遮罩層 if(config.modal){ self.$drag_modal=document.createElement('div'); self.$drag_modal.className='drag_modal'; fragment.appendChild(self.$drag_modal); }
//建立內容 self.$drag_content=document.createElement('div'); self.$drag_content.className='drag_content'; self.$drag_content.innerHTML=` <divclass="drag_head"> ${config.title} <ahref="javascript:;"class="drag_close"></a> </div> <divclass="drag_main">${config.template}</div> ${config.buttons.length>0? `<divclass="drag_foot"> ${config.buttons.map((item,index)=>{ return`<ahref="javascript:;"class="drag_button"index="${index}">${item.text}</a>` }).join('')} </div>` :``} `;
fragment.appendChild(self.$drag_content); //把動態元素新增到頁面當中 document.body.appendChild(fragment); fragment=null;
//控制元素顯示 self.$drag_content.offsetHeight;//重新整理渲染佇列 self.$drag_modal?self.$drag_modal.style.opacity=1:null; self.$drag_content?self.$drag_content.style.opacity=1:null;
//改變盒子居中的方式 letHTML=document.documentElement; self.$drag_content.style.left=`${(HTML.clientWidth-self.$drag_content.clientWidth)/2}px`; self.$drag_content.style.top=`${(HTML.clientHeight-self.$drag_content.clientHeight)/2}px`; self.$drag_content.style.transform='translate(0,0)';
//觸發開發的周期函式 self.config.onopen.call(self,self); }, //關閉彈窗 close(){ letself=this, body=document.body; if(self.$drag_modal){ self.$drag_modal.style.opacity=0; //動畫結束之後移除元素 self.$drag_modal.ontransitionend=()=>{ body.removeChild(self.$drag_modal); self.$drag_modal.ontransitionend=null; } }
if(self.$drag_content){ self.$drag_content.style.opacity=0; //動畫結束之後移除元素 self.$drag_content.ontransitionend=()=>{ body.removeChild(self.$drag_content); self.$drag_content.ontransitionend=null; //觸發關閉的周期函式 self.config.onclose.call(self,self); } } }, //拖拽系列方法 down(ev){ letself=this;
self.startX=ev.pageX; self.startY=ev.pageY; self.startL=self.$drag_content.offsetLeft; self.startT=self.$drag_content.offsetTop; self._MOVE=self.move.bind(self); self._UP=self.up.bind(self); document.addEventListener('mousemove',self._MOVE); document.addEventListener('mouseup',self._UP); //通知事件池中的方法執行 self.ondragstart.fire(self); }, move(ev){ letself=this, curL=ev.pageX-self.startX+self.startL, curT=ev.pageY-self.startY+self.startT;
//邊界判斷 letHTML=document.documentElement, minL=0, minT=0, maxL=HTML.clientWidth-self.$drag_content.offsetWidth, maxT=HTML.clientHeight-self.$drag_content.offsetHeight;
curL=curL<minL?minL:(curL>maxL?maxL:curL); curT=curT<minT?minT:(curT>maxT?maxT:curT);
self.$drag_content.style.left=`${curL}px`; self.$drag_content.style.top=`${curT}px`; //通知事件池中的方法執行 self.ondraging.fire(self); }, up(){ letself=this; document.removeEventListener('mousemove',self._MOVE); document.removeEventListener('mouseup',self._UP); //通知事件池中的方法執行 self.ondragend.fire(self); } } //暴露的API //定義每一個引數規則 constprops={ title:{ type:'string', default:"系統溫馨提示" }, template:{ type:'string', required:true }, buttons:{ type:'array', default:[] }, modal:{ type:'boolean', default:true }, drag:{ type:'boolean', default:true }, drag:{ type:'boolean', default:true }, onopen:{ type:'function', default:()=>{} }, onclose:{ type:'function', default:()=>{} }, }
constproxyModal=functionproxyModal(options){ //驗證配置項 !options||!utils.isPlainObject(options)?options={}:null;
//console.log(options); letconfig={}; utils.each(props,(key,rule)=>{ letopValue=options[key], {type,default:defaultValue,required}=rule; //options沒有傳遞配置項:驗證是否為必傳&&取引數預設值 if(typeofopValue==='undefined'){ if(required)thrownewTypeError(`${key}mustberequired`); config[key]=defaultValue return; } //options有傳遞key這一項,驗證值的格式&&取傳進來的值 if(utils.toType(opValue)!==type)thrownewTypeError(`${key}mustbean${type}`); //物件合併 config[key]=utils.merge(defaultValue,opValue); }); returnnewModalPlugin(config); };
if(typeofwindow!=="undefined"){ window.M=window.ModalPlugin=proxyModal; }
if(typeofmodule==="object"&&typeofmodule.exports==='object'){ module.exports=proxyModal; } ----------------------------------------- sub.js functionSub(){ this.pond=[]; } Sub.prototype={ constructor:Sub, on(func){ letpond=this.pond; !pond.includes(func)?pond.push(func):null; }, off(func){ letpond=this.pond; pond.forEach((item,index)=>item===func?pond[index]=null:null); }, fire(...params){ letpond=this.pond; for(leti=0;i<pond.length;i++){ letitemFunc=pond[i]; if(typeofitemFunc!=="function"){ pond.splice(i,1); i--; continue; } itemFunc(...params); } } }; exportdefaultSub; --------------------------- vargetProto=Object.getPrototypeOf; varclass2type={}; vartoString=class2type.toString; varhasOwn=class2type.hasOwnProperty; varfnToString=hasOwn.toString; varObjectFunctionString=fnToString.call(Object);
[ "Boolean", "Number", "String", "Symbol", "Function", "Array", "Date", "RegExp", "Object", "Error" ].forEach(function(name){ class2type["[object"+name+"]"]=name.toLowerCase(); });
functiontoType(obj){ if(obj==null){ returnobj+""; } returntypeofobj==="object"||typeofobj==="function"? class2type[toString.call(obj)]||"object": typeofobj; }
functionisPlainObject(obj){ varproto, Ctor, type=toType(obj); if(!obj||type!=="object"){ returnfalse; } proto=getProto(obj); if(!proto){ returntrue; } Ctor=hasOwn.call(proto,"constructor")&&proto.constructor; returntypeofCtor==="function"&&fnToString.call(Ctor)===ObjectFunctionString; }
functionisFunction(obj){ returntypeofobj==="function"&&typeofobj.nodeType!=="number"; };
functionisWindow(obj){ returnobj!=null&&obj===obj.window; };
functionisArrayLike(obj){ varlength=!!obj&&"length"inobj&&obj.length, type=toType(obj); if(isFunction(obj)||isWindow(obj)){ returnfalse; } returntype==="array"||length===0|| typeoflength==="number"&&length>0&&(length-1)inobj; }
functionmerge(obj1,obj2){ letisPlain1=isPlainObject(obj1), isPlain2=isPlainObject(obj2); if(!isPlain1)returnobj2; if(!isPlain2)returnobj1; [ ...Object.getOwnPropertyNames(obj2), ...Object.getOwnPropertySymbols(obj2) ].forEach(key=>{ obj1[key]=merge(obj1[key],obj2[key]); }); returnobj1; }
functioneach(obj,callback){ varlength,i=0; if(isArrayLike(obj)){ length=obj.length; for(;i<length;i++){ if(callback.call(obj[i],i,obj[i])===false){ break; } } }else{ varkeys=[ ...Object.getOwnPropertyNames(obj), ...Object.getOwnPropertySymbols(obj) ]; for(;i<keys.length;i++){ varkey=keys[i], value=obj[key]; if(callback.call(value,key,value)===false){ break; } } } returnobj; }
exportdefault{ toType, isPlainObject, isFunction, isWindow, isArrayLike, merge, each }; utils.js -> 封裝好的工具類-》js型別驗證 我是Eric,手機號是13522679763