原生Javascript插件開發實踐


前言

之前公司設計的網站比較混亂,很多地方不統一,其中一個就是彈出層,導致這個原因是因為,公司的UI換了好幾個人,而他們每個人做出來的都不太一樣。最近公司開始整頓這個問題,對於統一的這種東西當然是做成一個模塊,或者插件,而我打算做成插件。之所以寫這篇文章是因為,當寫完這個插件以后,發現其中有不少的理念,而這些理念我想把它總結一下,雖然這個插件並不復雜。

該怎樣架構?

對於架構這個概念,接觸的比較少,我的理解,架構就是解決未來可能會發生的事。

之前也封裝過一些插件,但后端嫌我封裝的太難用,於是分析其原因,發現之前寫的插件,該暴露的接口沒有,有些不需要傳的參數反而要傳。該暴露的接口沒有,這是因為我沒有按照未來的思想來寫插件,而往往這樣寫出來的插件就成了一次性用品。

所以這段時間,在寫插件之前都會事先思考清楚,這個插件都需要哪些參數,而哪些又是必須傳的,哪些是可選的,哪些功能以后可能會用到,哪些是可以會更改的,這些都是必須考慮的,不然寫出來的插件肯定會有很多的問題。

基本雛形

;(function(window,document){
	var MaskShare = function(){

	};
	MaskShare.prototype = {};

	window.MaskShare = MaskShare;
}(window,document));

把要寫的代碼,封閉到一個自執行函數里面,防止變量沖突,然后將這個構造函數暴露給window對象,方便我們在外部去訪問這個構造函數。

效果需要做成如下的:

思考需要哪些參數

這個功能就是點擊某個元素,彈出一個遮罩層,點擊遮罩層將遮罩層去掉。

因此可以分析出,至少需要一個參數,也就是我們需要知道點擊誰彈出彈出層,另外我們還需要配置一些默認參數。

;(function(window,document){
	var MaskShare = function(targetDom,options){
		// 判斷是用函數創建的還是用new創建的。這樣我們就可以通過MaskShare("dom") 或 new MaskShare("dom")來使用這個插件了
		if(!(this instanceof MaskShare))return new MaskShare(targetDom,options);

		// 參數合並
		this.options = this.extend({
                        // 這個參數以后可能會更改所以暴露出去
			imgSrc:"../static/img/coupon-mask_1.png"
		},options);

		// 判斷傳進來的是DOM還是字符串
		if((typeof targetDom)==="string"){
			this.targetDom = document.querySelector(targetDom);
		}else{
			this.targetDom = targetDom;
		}

		var boxDom = document.createElement("div");
		var imgDom = document.createElement("img");

		// 設置默認樣式 注意將z-index值設置大一些,防止其他元素層級比遮罩層高
		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;";
		imgDom.style.cssText = "margin-top:20px;width: 100%;";

		// 追加或重設其樣式
		if(this.options.boxDomStyle){
			this.setStyle(boxDom,this.options.boxDomStyle);
		}
		if(this.options.imgDomStyle){
			this.setStyle(imgDom,this.options.imgDomStyle);
		}

		imgDom.src = this.options.imgSrc;
		boxDom.appendChild(imgDom);
		this.boxDom = boxDom;

		// 初始化
		this.init();
	};
	MaskShare.prototype = {
		init:function(){
			this.event();
		},
		extend:function(obj,obj2){
			for(var k in obj2){
				obj[k] = obj2[k];
			}
			return obj;
		},
		setStyle:function(dom,objStyle){
			for(var k in objStyle){
				dom.style[k] = objStyle[k];
			}
		},
		event:function(){
			var _this = this;

			this.targetDom.addEventListener("click",function(){
				document.body.appendChild(_this.boxDom);
				_this.boxDom.style.display = "block";
                                // 打開遮罩層的回調
				_this.options.open&&_this.options.open();
			},false);

			this.boxDom.addEventListener("click",function(){
				this.style.display = "none";
                                // 關閉遮罩層的回調
				_this.options.close&&_this.options.close();
			},false);
		}
	};
	// 暴露方法
	window.MaskShare = MaskShare;
}(window,document));

使用示例:

MaskShare(".immediately",{
	imgSrc:"../static/img/loading_icon.gif",
	boxDomStyle:{
		opacity:".9"
	},
	imgDomStyle:{
		opacity:".8"
	},
	open:function(){
		console.log("show");
	},
	close:function(){
		console.log("close");
	}
});

本次總結

此時再分析一遍,發現其還是有很多局限性,比如,如果不使用圖片用到的是一段文字呢,又該怎么辦?這些都是很大的問題,要寫出一個實用的插件,不僅僅技術需要過關,思考還得全面性。所以這篇文章還只是剛剛開始,路還遠着呢。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM