JS 組合模式更經常使用於建立表單上,好比註冊頁面可能有不一樣的表單提交模塊。對於這些需求咱們只須要有基本的個體,而後經過必定的組合便可實現,好比下面這個頁面樣式(如圖14-2所示),咱們來用組合模式實現。html
做者給的提示,首先建立基類 Base, 而後三個組合類 FormItem、FieldsetItem、Group,以及成員類InputItem、LabelItem、SpanItem、TextareaItem,建立完以後像下面這樣拼出你的註冊頁面吧。app
var form = new FormItem('FormItem', document.body); form.add( new FieldsetItem('account', '帳號').add( new Group().add( new LabelItem('user_name', '用戶名:') ).add( new InputItem('user_name') ).add( new SpanItem('4到6位數字或字母') ) ).add( new Group().add( new LabelItem('user_password', '密 碼:') ).add( new InputItem('user_password') ).add( new SpanItem('6到12位數字或者密碼') ) ) ).add( new FieldsetItem('info', '信息').add( new Group().add( new LabelItem('pet_name', '暱稱:') ).add( new InputItem('user_pet_name') ) ).add( new Group().add( new LabelItem('user_status', '狀態:') ).add( new InputItem('user_status') ) ) )
下面咱們來挨個建立個體類。函數
// 原型式繼承 function inheritObject(o) { // 聲明一個過渡函數對象 function F() {} // 過渡函數的原型繼承父對象 F.prototype = o; // 返回過渡對象的一個實例,該實例的原型繼承了父對象 return new F(); } /** * 寄生式繼承 繼承原型 * 傳遞參數 subClass 子類 * 傳遞參數 superClass 父類 **/ function inheritPrototype(subClass, superClass) { // 複製一份父類的原型副本保存在變量中 var p = inheritObject(superClass.prototype); // 修正由於重寫子類原型致使子類的constructor屬性被修改 p.constructor = subClass; // 設置子類的原型 subClass.prototype = p; }
首先建立總的虛擬父類 Form測試
var Form = function() { // 子組件容器 this.children = []; // 當前組件元素 this.element = null; } Form.prototype = { init: function() { throw new Error('請重寫你的方法'); }, add: function() { throw new Error('請重寫你的方法'); }, getElement: function() { throw new Error('請重寫你的方法'); }, }
FormItem 容器構造函數this
var FormItem = function(id, parent) { // 構造函數繼承父類 Form.call(this); // 模塊id this.id = id; // 模塊的父容器 this.parent = parent; // 構建方法 this.init(); } // 寄生式繼承父類原型方法 inheritPrototype(FormItem, Form); // 構建方法 FormItem.prototype.init = function() { this.element = document.createElement('form'); this.element.id = this.id; this.element.className = 'new-form'; } FormItem.prototype.add = function(child) { // 在子元素容器中插入子元素 this.children.push(child); // 插入當前組件元素樹中 this.element.appendChild(child.getElement()); return this; } // 獲取當前元素方法 FormItem.prototype.getElement = function() { return this.element; } // 顯示方法 FormItem.prototype.show = function() { this.parent.appendChild(this.element); }
FieldsetItem 容器構造函數spa
var FieldsetItem = function(id, fieldName) { Form.call(this); this.fieldName = fieldName || ''; this.init(); } inheritPrototype(FieldsetItem, Form); FieldsetItem.prototype.init = function() { this.element = document.createElement('fieldset'); var legend = document.createElement('legend'); legend.innerHTML = this.fieldName; this.element.appendChild(legend); } FieldsetItem.prototype.add = function(child) { this.children.push(child); this.element.appendChild(child.getElement()); return this; } FieldsetItem.prototype.getElement = function() { return this.element; }
Group 容器構造函數prototype
var Group = function() { Form.call(this); this.init(); } inheritPrototype(Group, Form); Group.prototype.init = function() { this.element = document.createElement('div'); } Group.prototype.add = function(child) { this.children.push(child); this.element.append(child.getElement()); } Group.prototype.getElement = function() { return this.element; }
InputItem 容器構造函數code
var InputItem = function(id, name) { Form.call(this); this.name = name; this.init(); } inheritPrototype(InputItem, Form); InputItem.prototype.init = function() { this.element = document.createElement('input'); this.element.id = this.id; this.element.type = 'text'; this.element.name = this.name; } InputItem.prototype.add = function() {} InputItem.prototype.getElement = function() { return this.element; }
LabelItem 容器構造函數orm
var LabelItem = function(labelFor, labelText) { Form.call(this); this.labelFor = labelFor; this.labelText = labelText; this.init(); } LabelItem.prototype.init = function() { this.element = document.createElement('label'); this.element.htmlFor = this.labelFor; this.element.innerText = this.labelText; } LabelItem.prototype.add = function() {} LabelItem.prototype.getElement = function() { return this.element; }
SpanItem 容器構造函數 htm
var SpanItem = function(spanText) { Form.call(this); this.spanText = spanText; this.init(); } inheritPrototype(SpanItem, Form); SpanItem.prototype.init = function() { this.element = document.createElement('span'); this.element.innerText = this.spanText; } SpanItem.prototype.add = function() {} SpanItem.prototype.getElement = function() { return this.element; }
代碼已經寫完,稍等,我來測試一下。。。。。。