1. 程式人生 > >面向對象權限配置組件 (面向對象編程 組件化開發)

面向對象權限配置組件 (面向對象編程 組件化開發)

++ dom attribute select 會計 ner 構建 code sel

1.組件結構

技術分享

2.頁面調用

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>面向對象權限配置組件</title>
	<link rel="stylesheet" type="text/css" href="assets/UserRoleSelector/css/UserRoleSelector.css">
</head>
<body>
	<button id="showSelector">配置用戶角色</button>

	<script src="assets/UserRoleSelector/js/UserRoleSelector.js"></script>

	<script>
		window.onload = function(){
			// 通過構造器傳入參數,構建UserRoleSelector的實例
			var selector = new UserRoleSelector({ // 傳參
				show : false, // 默認不顯示
				data : [{"value":"1","text":"系統管理員"},
						{"value":"2","text":"部門經理"},
						{"value":"3","text":"部門主管"},
						{"value":"4","text":"銷售經理"},
						{"value":"5","text":"財務會計"},
						{"value":"6","text":"財務出納"}], // 數據列表 傳入json對象
				onSave : function(){ // 保存 傳參  參數為組件本身
					alert(this.getValues()); // do code
					// console.log(this); // 問題:改變不了this的引用
					// this.getValues(); // 獲得當前被選中的數據
					this.hide(); // 此時this指向UserRoleSelector
				}
			});
			document.getElementById("showSelector").onclick = function(){
				if(selector.status){
					selector.hide();
				}else{
					selector.show(); // 讓組件出現
				}
			}
		}
	</script>
</body>
</html>

3.組件封裝:

UserRoleSelector.css

html,body{
	width: 100%;
	height: 100%;
	margin: 0;
	padding: 0;
	font-family: Airal,‘microsoft yahei‘;
	background-color: #b1b1b1;
	-moz-user-select: none;/*火狐*/
	-webkit-user-select: none;/*webkit瀏覽器*/
	-ms-user-select: none;/*IE10*/
	-khtml-user-select: none;/*早期瀏覽器*/
	user-select: none;
	overflow: hidden;
}
ul,li{
	list-style: none;
	margin: 0;
	padding: 0;
}
.mask{
	position: fixed;
	top: 0;
	bottom: 0;
	left: 0;
	right: 0;
	background-color: rgba(0,0,0,.5);
}
.user-role-selector{
	position: absolute;
	top: 50%;
	left: 50%;
	margin-left: -290px;
	margin-top: -250px;
	background-color: #fff;
	border-radius: 2px;/*邊角半徑*/
	padding: 50px 20px;
	width: 540px;
	height: 400px;
}
.user-role-selector .data-list{
	width: 40%;
	height: 90%;
	background-color: #fafafa;
	border: 1px solid #e5e5e5;
	float: left;
}
.user-role-selector .data-list li{
	width: 100%;
	height: 36px;
	line-height: 36px;
	text-indent: 10px;
	color: #666;
	font-size: 14px;
	cursor: pointer;
}
.user-role-selector .data-list li:hover{
	background-color: #039ae3;
	color: #fff;
}
.user-role-selector .data-list li.selected{
	background-color: #666;
	color: #fff;
}
.user-role-selector .data-oper{
	width: 18%;
	height: 100%;
	float: left;
	padding-top: 25%;
}
.user-role-selector .data-oper .button{
	margin: 20px auto;
	text-align: center;
}
.user-role-selector .button{
	width: 80px;
	height: 36px;
	display: block;
	border: 1px solid #d9d9d9;
	line-height: 36px;
	text-decoration: none;
	color: #333;
	background: #f3f3f3;
	font-size: 14px;
}
.user-role-selector .button:hover{
	background-color: #039ae3;
	color: #fff;
}
.user-role-selector .data-bar{
	position: absolute;
	bottom: 20px;
	left: 0;
	width: 100%;
	height: 10%;
}
.user-role-selector .data-bar .button{
	float: right;
	text-align: center;
	margin-right: 25px;
}
.user-role-selector .data-bar .button.close{
	background-color: #e84c4c;
	color: #fff;
}

UserRoleSelector.js

// 創建閉包 避免變量汙染(全局汙染)
var UserRoleSelector = (function(){
	/**
	 * 1.構建 構造器函數
	 * 一般首字母大寫
	 */
	// 2.定義UserRoleSelector類型構造器
	function UserRoleSelector(options) { // 3.用戶傳入的參數
		// this.options = options||{}; // 4.為了避免用戶不傳入options對象造成的NullPointer(空指針異常)
		this.init(options||{}); // 5.初始化操作
		// this.render(); // 9.生成(渲染)dom結構
		this.bind(); // 綁定插件中dom需要的所有事件
	}
	// 11.將要被渲染的dom結構
	var html = 
		‘<div class="user-role-selector">‘ +
			‘<ul class="left-list data-list">‘ +
				// ‘<li>系統管理員</li>‘ +
				// ‘<li>部門經理</li>‘ +
				// ‘<li>部門組管</li>‘ +
				// ‘<li>銷售經理</li>‘ +
				// ‘<li>財務會計</li>‘ +
				// ‘<li>財務出納</li>‘ +
			‘</ul>‘ +
			‘<div class="data-oper">‘ +
				‘<a href="#" class="add button">添加</a>‘ +
				‘<a href="#" class="del button">刪除</a>‘ +
			‘</div>‘ +
			‘<ul class="right-list data-list"></ul>‘ +
			‘<div class="data-bar"><a href="#" class="close button">關閉</a>‘ +
			‘<a href="#" class="save button">保存</a></div>‘ +
		‘</div>‘;

	// 6.擴展UserRoleSelector類型實例的功能
	UserRoleSelector.prototype = {
		init:function(options) { // 7.初始化操作
			this.options = options; // 8.初始化參數
			this.dom = document.createElement("div");// 12.創建元素
			this.dom.className = "mask";
			this.dom.style.display = this.options.show?"block":"none"; // 由用戶決定元素是否顯示
			this.dom.innerHTML = html;
			this.status = this.options.show?1:0; // 0代表隱藏  1代表顯示
			document.body.appendChild(this.dom); // 13.將dom插入到新創建的div元素中
			// 27.找到左右列表 便於接受index.html傳入數據列表參數
			this.left = this.dom.querySelector(".left-list.data-list");
			this.right = this.dom.querySelector(".right-list.data-list");
			// 32.add、del按鈕
			this.add = this.dom.querySelector(".button.add"); // 尋找add按鈕
			this.del = this.dom.querySelector(".button.del"); // 尋找del按鈕
			// 18.save、close按鈕
			this.save = this.dom.querySelector(".button.save"); // 尋找save按鈕
			// console.log(this.save);
			this.close = this.dom.querySelector(".button.close"); // 尋找close按鈕
			// 28.循環輸出列表數據
			var data = this.options.data||[];
			for(var i=0;i<data.length;i++){
				this.left.innerHTML+="<li data-value=‘"+data[i].value+"‘>"+data[i].text+"</li>";
			}
			this.items = this.left.querySelectorAll("li");// 29.找到所有的li
			// console.log(this.items.length);
		},
		// render:function() { // 10.渲染dom
		// 	this.dom.innerHTML = html;
		// },
		bind:function() { // 16.綁定插件中dom需要的所有事件
			var _this = this; // 21.此處this為UserRoleSelector組件本身,將組件的引用保存在局部變量_this中
			if(this.options.onSave){ // 23.保存方法 判斷用戶是否傳參
				// this.save.onclick = function() { // 24.方法一:外層包一個function 便於改變this的引用 及 接收參數
				// 	_this.options.onSave.call(_this); // 25.call方法 起到函數調用過程中改變this的引用,將作用域改為this(此處指向UserRoleSelector組件本身)
				// }
				this.save.onclick = _this.options.onSave.bind(_this); // 26.方法二:調用bind方法,直接參入_this,調用onclick方法,返回的是個函數 起到函數調用過程中,_this對象指向this
			}
			// 17.找到當前dom對象中的按鈕 寫在init方法中
			this.close.onclick = function() { // 19.定義close按鈕的綁定事件
				// this.hide(); // 隱藏組件
				_this.hide(); // 22.隱藏組件 使用局部變量_this替換this,使得指向為UserRoleSelector組件
				// 20.註意:因為函數的作用域問題,當函數被調用過程中,this指向函數本身,此處為close對象,而我們想指向UserRoleSelector組件,所有需要配置this
			};
			// this.add.onclick = function(){
			// 	// 33.拿到left下面所有被選中的item(.selected)
			// 	var selecteds = _this.left.querySelectorAll("li.selected");
			// 	// 34.往right裏面append
			// 	for(var i=0;i<selecteds.length;i++){
			// 		_this.right.appendChild(selecteds[i]);
			// 	}
			// };
			// this.del.onclick = function(){
			// 	// 35.拿到right下面所有被選中的item(.selected)
			// 	var selecteds = _this.right.querySelectorAll("li.selected");
			// 	// 36.往left裏面append
			// 	for(var i=0;i<selecteds.length;i++){
			// 		_this.left.appendChild(selecteds[i]);
			// 	}
			// };
			/**
			 * bind 和 call 的區別
			 * bind返回的是一個函數,將來時
			 * call返回的是一個對象,現在進行時
			 */
			this.add.onclick = this._operClick.bind(this,this.add); // 39.簡化代碼
			this.del.onclick = this._operClick.bind(this,this.del); // 39.簡化代碼
			// 30.給所有的li,綁定事件
			for(var i=0;i<this.items.length;i++){
				// this.items[i].onclick = function() {
				// 	// 31.給被點擊的元素添加樣式,再次點擊清除被選中樣式
				// 	if(this.className.indexOf("selected")!=-1){ // 清除被選中樣式
				// 		this.className = "";
				// 	}else{ // 添加被選中樣式
				// 		this.className = "selected";
				// 	}
				// }

				this.items[i].onclick = this._itemClick; // 38.調用私有方法
			}
		},
		show:function() { // 14.定義show方法
			this.dom.style.display = "block";
			this.status = 1;
		},
		hide:function() { // 15.定義hide方法
			this.dom.style.display = "none";
			this.status = 0;
		},
		_itemClick:function() { // 37.定義私有方法,提高代碼效率,節約內存空間
			if(this.className.indexOf("selected")!=-1){ // 清除被選中樣式
				this.className = "";
			}else{ // 添加被選中樣式
				this.className = "selected";
			}
		},
		_operClick:function(target){ // 40.定義私有方法
			// console.log(target);
			// 41.封裝方法
			var one,two;
			if(target.className.indexOf("add")!=-1){
				one = this.left;
				two = this.right;
			}else{
				one = this.right;
				two = this.left;
			}
			// 拿到one下面所有被選中的item(.selected)
			var selecteds = one.querySelectorAll("li.selected");
			// 往two裏面append
			for(var i=0;i<selecteds.length;i++){
				two.appendChild(selecteds[i]);
			}
		},
		getValues:function(){ // 43.獲得當前被選中的數據
			var values = "";
			var selecteds = this.right.querySelectorAll("li"); // 44.獲得右列表所有數據
			// 45.循環輸出
			for(var i=0;i<selecteds.length;i++){
				values+=selecteds[i].getAttribute("data-value");
				if(i!=selecteds.length-1){
					values+=",";
				}
			}
			return values;
		}
	}; // 每一個構造器函數都有一個prototype屬性

	// 構造器函數 與 普通函數 的區別
	// new UserRoleSelector(); // 調用構造器函數  創建一個被持有句柄的閉包空間,運行函數裏面的代碼(生命周期比普通函數長),this指向就是當前這塊這塊空間的引用

	// show(); // 調用普通函數  創建一個臨時閉包空間,運行函數裏面的代碼,this指向是window對象
	return UserRoleSelector; // 
})();

.

面向對象權限配置組件 (面向對象編程 組件化開發)