原生Javascript插件开发实践

前言

之前公司设计的网站比较混乱,很多地方不统一,其中一个就是弹出层,导致这个原因是因为,公司的UI换了好几个人,而他们每个人做出来的都不太一样。最近公司开始整顿这个问题,对于统一的这种东西当然是做成一个模块,或者插件,而我打算做成插件。之所以写这篇文章是因为,当写完这个插件以后,发现其中有不少的理念,而这些理念我想把它总结一下,虽然这个插件并不复杂。

该怎样架构

对于架构这个概念,接触的比较少,我的理解,架构就是解决未来可能会发生的事。

之前也封装过一些插件,但后端嫌我封装的太难用,于是分析其原因,发现之前写的插件,该暴露的接口没有,有些不需要传的参数反而要传。该暴露的接口没有,这是因为我没有按照未来的思想来写插件,而往往这样写出来的插件就成了一次性用品。

所以这段时间,在写插件之前都会事先思考清楚,这个插件都需要哪些参数,而哪些又是必须传的,哪些是可选的,哪些功能以后可能会用到,哪些是可以会更改的,这些都是必须考虑的,不然写出来的插件肯定会有很多的问题。

基本雏形

[javascript] view plain copy
 
  1. (function(window,document){  
  2.     var MaskShare = function(){  
  3.   
  4.     };  
  5.     MaskShare.prototype = {};  
  6.   
  7.     window.MaskShare = MaskShare;  
  8. }(window,document));  

 

 

把要写的代码,封闭到一个自执行函数里面,防止变量冲突,然后将这个构造函数暴露给window对象,方便我们在外部去访问这个构造函数。

效果需要做成如下的:

思考需要哪些参数

这个功能就是点击某个元素,弹出一个遮罩层,点击遮罩层将遮罩层去掉。

因此可以分析出,至少需要一个参数,也就是我们需要知道点击谁弹出弹出层,另外我们还需要配置一些默认参数。

[javascript] view plain copy
 
  1. (function(window,document){  
  2.     var MaskShare = function(targetDom,options){  
  3.         // 判断是用函数创建的还是用new创建的。这样我们就可以通过MaskShare("dom") 或 new MaskShare("dom")来使用这个插件了  
  4.         if(!(this instanceof MaskShare))return new MaskShare(targetDom,options);  
  5.   
  6.         // 参数合并  
  7.         this.options = this.extend({  
  8.                         // 这个参数以后可能会更改所以暴露出去  
  9.             imgSrc:"../static/img/coupon-mask_1.png"  
  10.         },options);  
  11.   
  12.         // 判断传进来的是DOM还是字符串  
  13.         if((typeof targetDom)==="string"){  
  14.             this.targetDom = document.querySelector(targetDom);  
  15.         }else{  
  16.             this.targetDom = targetDom;  
  17.         }  
  18.   
  19.         var boxDom = document.createElement("div");  
  20.         var imgDom = document.createElement("img");  
  21.   
  22.         // 设置默认样式 注意将z-index值设置大一些,防止其他元素层级比遮罩层高  
  23.         boxDom.style.cssText = "display: none;position: absolute;left: 0;top: 0;width: 100%;height:100%;background-color: rgba(0,0,0,0.8);z-index:9999;";  
  24.         imgDom.style.cssText = "margin-top:20px;width: 100%;";  
  25.   
  26.         // 追加或重设其样式  
  27.         if(this.options.boxDomStyle){  
  28.             this.setStyle(boxDom,this.options.boxDomStyle);  
  29.         }  
  30.         if(this.options.imgDomStyle){  
  31.             this.setStyle(imgDom,this.options.imgDomStyle);  
  32.         }  
  33.   
  34.         imgDom.src = this.options.imgSrc;  
  35.         boxDom.appendChild(imgDom);  
  36.         this.boxDom = boxDom;  
  37.   
  38.         // 初始化  
  39.         this.init();  
  40.     };  
  41.     MaskShare.prototype = {  
  42.         init:function(){  
  43.             this.event();  
  44.         },  
  45.         extend:function(obj,obj2){  
  46.             for(var k in obj2){  
  47.                 obj[k] = obj2[k];  
  48.             }  
  49.             return obj;  
  50.         },  
  51.         setStyle:function(dom,objStyle){  
  52.             for(var k in objStyle){  
  53.                 dom.style[k] = objStyle[k];  
  54.             }  
  55.         },  
  56.         event:function(){  
  57.             var _this = this;  
  58.   
  59.             this.targetDom.addEventListener("click",function(){  
  60.                 document.body.appendChild(_this.boxDom);  
  61.                 _this.boxDom.style.display = "block";  
  62.                                 // 打开遮罩层的回调  
  63.                 _this.options.open&&_this.options.open();  
  64.             },false);  
  65.   
  66.             this.boxDom.addEventListener("click",function(){  
  67.                 this.style.display = "none";  
  68.                                 // 关闭遮罩层的回调  
  69.                 _this.options.close&&_this.options.close();  
  70.             },false);  
  71.         }  
  72.     };  
  73.     // 暴露方法  
  74.     window.MaskShare = MaskShare;  
  75. }(window,document));  

 

 

使用示例:

[html] view plain copy
 
  1. MaskShare(".immediately",{  
  2.     imgSrc:"../static/img/loading_icon.gif",  
  3.     boxDomStyle:{  
  4.         opacity:".9"  
  5.     },  
  6.     imgDomStyle:{  
  7.         opacity:".8"  
  8.     },  
  9.     open:function(){  
  10.         console.log("show");  
  11.     },  
  12.     close:function(){  
  13.         console.log("close");  
  14.     }  
  15. });  

 

 

本次总结

此时再分析一遍,发现其还是有很多局限性,比如,如果不使用图片用到的是一段文字呢,又该怎么办?这些都是很大的问题,要写出一个实用的插件,不仅仅技术需要过关,思考还得全面性。所以这篇文章还只是刚刚开始,路还远着呢

posted @ 2017-07-25 16:05  G-Beniot  阅读(191)  评论(0编辑  收藏  举报