JS設計模式——4.繼承(示例)

目的

我們的目的就是編寫一個用於創建和管理就地編輯域的可重用的模塊化API。它是指網頁上的一段普通文本被點擊後就變成一個配有一些按鈕的表單域,以便用戶就地對這段文本進行編輯。

 

思路

當用戶點擊時

1.將普通文本域隱藏

 

2.添加表單元素

 

3.設置表單元素的value

 

當用戶保存時

ajax通信保存內容

 

當用戶取消時

1.隱藏表單域

 

2.顯示文本域

 

3.設置文本域的value

 

類式繼承實現就地編輯

superClass的實現(input)

復制代碼

function EditInPlaceField(id, parent, value){

    this.id = id;

    this.value = value || 'default value';

    this.parentElement = parent;

 

    this.createElements(this.id);

    this.attachEvents();

}

EditInPlaceField.prototype = {

    createElements: function(){

        this.containerElement = document.createElement('p');

        this.parentElement.appendChild(this.containerElement);

 

        this.staticElement = document.createElement('span');

        this.containerElement.appendChild(this.staticElement);

        this.staticElement.innerHTML = this.value;

 

        this.fieldElement = document.createElement('input');

        this.fieldElement.type = 'text';

        this.fieldElement.value = this.value;

        this.containerElement.appendChild(this.fieldElement);

 

        this.saveButton = document.createElement('input');

        this.saveButton.type='button';

        this.saveButton.value="Save";

        this.containerElement.appendChild(this.saveButton);

 

        this.cancelBtton = document.createElement('input');

        this.cancelBtton.type = 'button';

        this.cancelBtton.value = 'Cancel';

        this.containerElement.appendChild(this.cancelBtton);

        this.convertToText();

    },

    attachEvents: function(){

        var that = this;

        addEvent(this.staticElement, 'click', function(){that.convertToEditable();});

        addEvent(this.saveButton, 'click', function(){ that.save();});

        addEvent(this.cancelBtton, 'click', function(){that.cancel()});

    },

    convertToEditable: function(){

        this.staticElement.style.display = 'none';

        this.fieldElement.style.display = 'inline';

        this.saveButton.style.display = 'inline';

        this.cancelBtton.style.display = 'inline';

 

        this.setValue(this.value);

    },

    save: function(){

        this.value = this.getValue();

        var that = this;

        var callback = {

            success: function(){that.convertToText();},

            failure: function(){alert('Error saving value.');}

        };

        ajaxRequest('GET', 'save.php?id'+this.id+'&value='+this.value, callback);

    },

    cancel: function(){

        this.convertToText();

    },

    convertToText: function(){

        this.fieldElement.style.display = 'none';

        this.saveButton.style.display = 'none';

        this.cancelBtton.style.display = 'none';

        this.staticElement.style.display = 'inline';

 

        this.setValue(this.value);

    },

    setValue: function(value){

        this.fieldElement.value = value;

        this.staticElement.innerHTML = value;

    },

    getValue: function(){

        return this.fieldElement.value;

    }

};

復制代碼

subClass的實現(textarea)

復制代碼

function EditInPlaceArea(id, parent, value){

    EditInPlaceArea.superclass.constructor.call(this, id, parent, value);

}

extend(EditInPlaceArea, EditInPlaceField);

EditInPlaceArea.prototype.createElements = function(id){

    this.containerElement = document.createElement('p');

    this.parentElement.appendChild(this.containerElement);

 

    this.staticElement = document.createElement('p');

    this.containerElement.appendChild(this.staticElement);

    this.staticElement.innerHTML = this.value;

 

    this.fieldElement = document.createElement('textarea');

    this.fieldElement.type = 'text';

    this.fieldElement.value = this.value;

    this.containerElement.appendChild(this.fieldElement);

 

    this.saveButton = document.createElement('input');

    this.saveButton.type='button';

    this.saveButton.value="Save";

    this.containerElement.appendChild(this.saveButton);

 

    this.cancelBtton = document.createElement('input');

    this.cancelBtton.type = 'button';

    this.cancelBtton.value = 'Cancel';

    this.containerElement.appendChild(this.cancelBtton);

    this.convertToText();

};

EditInPlaceArea.prototype.convertToEditable = function(){

    this.staticElement.style.display = 'none';

    this.fieldElement.style.display = 'block';

    this.saveButton.style.display = 'inline';

    this.cancelBtton.style.display = 'inline';

 

    this.setValue(this.value);

};

EditInPlaceArea.prototype.convertToText = function(){

    this.fieldElement.style.display = 'none';

    this.saveButton.style.display = 'none';

    this.cancelBtton.style.display = 'none';

    this.staticElement.style.display = 'block';

 

    this.setValue(this.value);

};

復制代碼

API的依賴與調用

addEvent依賴

復制代碼

function addEvent(el, ty, fn){

    if(el.addEvetListener){

        el.addEvetListener(ty, fn, false);

    }else if(el.attachEvent){

        el.attachEvent('on'+ty, fn);

    }else{

        el['on'+ty] = fn;

    }

}

復制代碼

extend依賴

復制代碼

function extend(subClass, superClass){

    var F = function(){};

    F.prototype = superClass.prototype;

    subClass.prototype = new F();

    subClass.prototype.constructor = subClass;

    subClass.superclass = superClass.prototype;

    if(superClass.prototype.constructor == Object.prototype.constructor){

        superClass.prototype.constructor = superClass;

    }

}

復制代碼

API的調用

var titleClassical = new EditInPlaceField('titleClassical', document.getElementById('titleClassical').parentNode, 'Title here');

var bodyClassical =new EditInPlaceArea('bodyClassical', document.getElementById('bodyClassical').parentNode, 'Body here');

發佈留言