Skip to main content
 首页 » 编程设计

javascript使用类式继承,原型式继承和掺元类三种不同解决方案

2022年07月16日30zhoujg
html: 
<!DOCTYPE HTML> 
<html lang="en-US"> 
<head> 
    <meta charset="UTF-8"> 
    <title></title> 
 
</head> 
<body> 
<p id="test"><span id="titleClassical">this an editable text content</span></p> 
 
<p id="test2"><span id="titleClassica2">this an editable text content</span></p> 
<script src="common.js"></script> 
<!-- 
 
类式继承解决方案,适用于相似度较大的类,和原型式继承可以互相转换 
 
<script src="edit-in-place-1.js"></script> 
<script> 
    var titleClassical = new EditInPlaceField('titleClassical', $('test'), 'this is a text'); 
    // 通过继承 
    var test2 = new EditInPlaceArea('titleClassical2', $('test2'), 'this is text2 content'); 
</script> 
 
--> 
 
<!-- 
 
原型式继承解决方案 
 
<script src="edit-in-place-2.js"></script> 
<script> 
    EditInPlaceField.configure('titleClassical', $('test'), 'this is a text'); 
 
    EditInPlaceArea.configure('titleClassical2', $('test2'), 'this is text2 content'); 
</script> 
--> 
 
<script src="edit-in-place-3.js"></script> 
<script> 
    //掺元类,适用于各类对象中的通用方法的共享 
    var titleClassical = new EditInPlaceField('titleClassical', $('test'), 'this is a text'); 
 
    var test2 = new EditInPlaceArea('titleClassical2', $('test2'), 'this is text2 content'); 
</script> 
</body> 
</html> 
 
 
comon js: 
function addEvent(obj, type, fn) { 
    if (obj.addEventListener) { 
        obj.addEventListener(type, fn, false); 
        EventCache.add(obj, type, fn); 
    } 
    else if (obj.attachEvent) { 
        obj["e" + type + fn] = fn; 
        obj[type + fn] = function () { 
            obj["e" + type + fn](window.event); 
        }; 
        obj.attachEvent("on" + type, obj[type + fn]); 
        EventCache.add(obj, type, fn); 
    } 
    else { 
        obj["on" + type] = obj["e" + type + fn]; 
    } 
} 
function $() { 
    var elements = new Array(); 
    for (var i = 0; i < arguments.length; i++) { 
        var element = arguments[i]; 
        if (typeof element == 'string') 
            element = document.getElementById(element); 
        if (arguments.length == 1) 
            return element; 
        elements.push(element); 
    } 
    return elements; 
}  
function clone(object) { 
    function F() { 
    } 
 
    F.prototype = object; 
    return new F(); 
} 
 
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; 
    } 
} 
 
function augment(receivingClass, givingClass) { 
    if (arguments[2]) { // Only give certain methods. 
        for (var i = 2, len = arguments.length; i < len; i++) { 
            receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]]; 
        } 
    } 
    else { // Give all methods. 
        for (methodName in givingClass.prototype) { 
            if (!receivingClass.prototype[methodName]) { 
                receivingClass.prototype[methodName] = givingClass.prototype[methodName]; 
            } 
        } 
    } 
} 
 
var Ajax = { 
    createXHR:function () { 
        if (typeof XMLHttpRequest !== 'undefined') { 
            return new XMLHttpRequest(); 
        } else if (typeof ActiveXObject !== 'undefined') { 
            if (typeof arguments.callee.activeXString !== 'string') { 
                var versions = ['MSXML2.XMLHttp.6.0', 'MSXML2.XMLHttp.3.0', 'MSXML2.XMLHttp']; 
                for (var i = 0, len = versions.length; i < len; i++) { 
                    try { 
                        var xhr = new ActiveXObject(versions[i]); 
                        arguments.callee.activeXString = versions[i]; 
                        return xhr; 
                    } catch (ex) { 
 
                    } 
                } 
            } 
            return new ActiveXObject(arguments.callee.activeXString); 
        } else { 
            throw new Error('No xhr object available'); 
        } 
    }, 
    responseType:function (request) { 
        var _responseType = request.getResponseHeader('Content-Type'); 
        switch (_responseType) { 
            case 'text/xml': 
                return request.responseXML; 
            case 'text/json': 
            case 'text/javascript': 
            case 'application/javascript': 
            case 'application/x-javascript': 
                return eval('(' + request.responseText + ')'); 
            default: 
                return request.responseText; 
        } 
    }, 
    encodeFormData:function (data) { 
        var _pairs = []; 
        var _regexp = /%20/g; 
        for (var name in data) { 
            var _value = data[name].toString(); 
            var _pair = encodeURIComponent(name).replace(_regexp, '+') + '=' + encodeURIComponent(_value).replace(_regexp, '+'); 
            _pairs.push(_pair); 
        } 
        return _pair.join('&'); 
    }, 
    /** 
     * 执行ajax请求 
     * @param {String} method 'GET' || 'POST' 
     * @param {String} url 
     * @param {Boolean} asyn 是否异步加载 
     * @param {Object} callback {success,failure} 回调对象,存放函数 
     * @param value 
     */ 
    ajaxRequest:function (method, url, asyn, callback, value) { 
        var _xhr = this.createXHR(); 
        _xhr.onreadystatechange = function () { 
            if (_xhr.readyState === 4) { 
                if (_xhr.status >= 200 && _xhr.status < 300 || _xhr.status === 300) { 
                    callback.success(this.responseType(_xhr)); 
                } else { 
                    if (callback.failure) { 
                        callback.failure(_xhr.status, _xhr.statusText); 
                    } 
                } 
            } 
        }; 
 
        _xhr.open(method, url, asyn); 
 
        if (method === 'GET') { 
            _xhr.send(null); 
        } else if (method === 'POST') { 
            _xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
            _xhr.send(this.encodeFormData(value)); 
        } 
    } 
}; 
 
 
 
edit-in-place-1.js  
 /** 
 * Created with JetBrains WebStorm. 
 * User: lindongpeng 
 * Date: 12-12-1 
 * Time: 下午10:05 
 */ 
 
/* EditInPlaceField class */ 
 
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 (id) { 
        this.containerElement = document.createElement('div'); 
        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.cancelButton = document.createElement('input'); 
        this.cancelButton.type = 'button'; 
        this.cancelButton.value = 'Cancel'; 
        this.containerElement.appendChild(this.cancelButton); 
 
        this.convertToText(); 
    }, 
    /** 
     * 添加事件 
     */ 
    attachEvents:function () { 
        var that = this; 
        addEvent(this.staticElement, 'click', function () { 
            that.convertToEditable(); 
        }); 
        addEvent(this.saveButton, 'click', function () { 
            that.save(); 
        }); 
        addEvent(this.cancelButton, 'click', function () { 
            that.cancel(); 
        }); 
    }, 
    /** 
     * 转换成可编辑状态 
     */ 
    convertToEditable:function () { 
        this.staticElement.style.display = 'none'; 
        this.fieldElement.style.display = 'inline'; 
        this.saveButton.style.display = 'inline'; 
        this.cancelButton.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'); 
            } 
        }; 
        Ajax.ajaxRequest('GET', 'save.php?id=' + this.id + '&value=' + this.value, true, callback); 
    }, 
    //取消编辑 
    cancel:function () { 
        this.convertToText(); 
    }, 
    convertToText:function () { 
        this.fieldElement.style.display = 'none'; 
        this.saveButton.style.display = 'none'; 
        this.cancelButton.style.display = 'none'; 
        this.staticElement.style.display = 'inline'; 
 
        this.setValue(this.value); 
    }, 
    setValue:function (value) { 
        this.fieldElement.valu = value; 
        this.staticElement.innerHTML = value; 
    }, 
    getValue:function () { 
        return this.fieldElement.value; 
    } 
}; 
 
// EditInPlaceArea class 
function EditInPlaceArea(id,parent,value){ 
    EditInPlaceArea.superclass.constructor.call(this,id,parent,value); 
} 
 
extend(EditInPlaceArea,EditInPlaceField); 
 
// Override certain methods 
EditInPlaceArea.prototype.createElements=function(id){ 
    this.containerElement=document.createElement('div'); 
    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.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.cancelButton=document.createElement('input'); 
    this.cancelButton.type='button'; 
    this.cancelButton.value='Cancel'; 
    this.containerElement.appendChild(this.cancelButton); 
 
    this.convertToText(); 
}; 
 
EditInPlaceArea.prototype.convertToEditable=function(){ 
    this.staticElement.style.display='none'; 
    this.fieldElement.style.display='block'; 
    this.saveButton.style.display='inline'; 
    this.cancelButton.style.display='inline'; 
 
    this.setValue(this.value); 
}; 
 
EditInPlaceArea.prototype.convertToText=function(){ 
    this.staticElement.style.display='block'; 
    this.fieldElement.style.display='none'; 
    this.saveButton.style.display='none'; 
    this.cancelButton.style.display='none'; 
 
    this.setValue(this.value); 
}; 
 
edit-in-place-2.js 
/** 
 * Created with JetBrains WebStorm. 
 * User: lindongpeng 
 * Date: 12-12-2 
 * Time: 下午8:17 
 */ 
 
var EditInPlaceField = { 
    configure:function (id, parent, value) { 
        this.id = id; 
        this.value = value || 'default value'; 
        this.parentElement = parent; 
 
        this.createElements(this.id); 
        this.attachEvents(); 
    }, 
    createElements:function (id) { 
        this.containerElement = document.createElement('div'); 
        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.cancelButton = document.createElement('input'); 
        this.cancelButton.type = 'button'; 
        this.cancelButton.value = 'Cancel'; 
        this.containerElement.appendChild(this.cancelButton); 
 
        this.convertToText(); 
    }, 
    attachEvents:function () { 
        var that = this; 
        addEvent(this.staticElement, 'click', function () { 
            that.convertToEditable(); 
        }); 
        addEvent(this.saveButton, 'click', function () { 
            that.save(); 
        }); 
        addEvent(this.cancelButton, 'click', function () { 
            that.cancel(); 
        }); 
    }, 
    convertToEditable:function () { 
        this.staticElement.style.display = 'none'; 
        this.fieldElement.style.display = 'inline'; 
        this.saveButton.style.display = 'inline'; 
        this.cancelButton.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'); 
            } 
        }; 
        Ajax.ajaxRequest('GET', 'save.php?id=' + this.id + '&value=' + this.value, true, callback); 
    }, 
    cancel:function () { 
        this.convertToText(); 
    }, 
    convertToText:function () { 
        this.fieldElement.style.display = 'none'; 
        this.saveButton.style.display = 'none'; 
        this.cancelButton.style.display = 'none'; 
        this.staticElement.style.display = 'inline'; 
 
        this.setValue(this.value); 
    }, 
    setValue:function (value) { 
        this.fieldElement.valu = value; 
        this.staticElement.innerHTML = value; 
    }, 
    getValue:function () { 
        return this.fieldElement.value; 
    } 
}; 
 
var EditInPlaceArea = clone(EditInPlaceField); 
 
EditInPlaceArea.createElements = function () { 
    this.containerElement = document.createElement('div'); 
    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.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.cancelButton = document.createElement('input'); 
    this.cancelButton.type = 'button'; 
    this.cancelButton.value = 'Cancel'; 
    this.containerElement.appendChild(this.cancelButton); 
 
    this.convertToText(); 
}; 
EditInPlaceArea.convertToEditable = function () { 
    this.staticElement.style.display = 'none'; 
    this.fieldElement.style.display = 'block'; 
    this.saveButton.style.display = 'inline'; 
    this.cancelButton.style.display = 'inline'; 
 
    this.setValue(this.value); 
}; 
EditInPlaceArea.convertToText = function () { 
    this.staticElement.style.display = 'block'; 
    this.fieldElement.style.display = 'none'; 
    this.saveButton.style.display = 'none'; 
    this.cancelButton.style.display = 'none'; 
 
    this.setValue(this.value); 
}; 
 
edit-in-place-3.js  
 /** 
 * Created with JetBrains WebStorm. 
 * User: lindongpeng 
 * Date: 12-12-2 
 * Time: 下午9:01 
 */ 
 
var EditInPlaceMixin = function () { 
}; 
EditInPlaceMixin.prototype = { 
    createElements:function (id) { 
        this.containerElement = document.createElement('div'); 
        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.cancelButton = document.createElement('input'); 
        this.cancelButton.type = 'button'; 
        this.cancelButton.value = 'Cancel'; 
        this.containerElement.appendChild(this.cancelButton); 
 
        this.convertToText(); 
    }, 
    attachEvents:function () { 
        var that = this; 
        addEvent(this.staticElement, 'click', function () { 
            that.convertToEditable(); 
        }); 
        addEvent(this.saveButton, 'click', function () { 
            that.save(); 
        }); 
        addEvent(this.cancelButton, 'click', function () { 
            that.cancel(); 
        }); 
    }, 
    convertToEditable:function () { 
        this.staticElement.style.display = 'none'; 
        this.fieldElement.style.display = 'inline'; 
        this.saveButton.style.display = 'inline'; 
        this.cancelButton.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'); 
            } 
        }; 
        Ajax.ajaxRequest('GET', 'save.php?id=' + this.id + '&value=' + this.value, true, callback); 
    }, 
    cancel:function () { 
        this.convertToText(); 
    }, 
    convertToText:function () { 
        this.fieldElement.style.display = 'none'; 
        this.saveButton.style.display = 'none'; 
        this.cancelButton.style.display = 'none'; 
        this.staticElement.style.display = 'inline'; 
 
        this.setValue(this.value); 
    }, 
    setValue:function (value) { 
        this.fieldElement.valu = value; 
        this.staticElement.innerHTML = value; 
    }, 
    getValue:function () { 
        return this.fieldElement.value; 
    } 
}; 
 
/* EditInPlaceField class */ 
function EditInPlaceField(id, parent, value) { 
    this.id = id; 
    this.value = value || 'default value'; 
    this.parentElement = parent; 
 
    this.createElements(this.id); 
    this.attachEvents(); 
} 
augment(EditInPlaceField, EditInPlaceMixin); 
 
 
/* EditInPlaceArea class */ 
function EditInPlaceArea(id, parent, value) { 
    this.id = id; 
    this.value = value || 'default value'; 
    this.parentElement = parent; 
 
    this.createElements(this.id); 
    this.attachEvents(); 
} 
 
// add certain method so that augment won't include them 
EditInPlaceArea.prototype.createElements = function (id) { 
    this.containerElement = document.createElement('div'); 
    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.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.cancelButton = document.createElement('input'); 
    this.cancelButton.type = 'button'; 
    this.cancelButton.value = 'Cancel'; 
    this.containerElement.appendChild(this.cancelButton); 
 
    this.convertToText(); 
}; 
EditInPlaceArea.prototype.convertToEditable = function () { 
    this.staticElement.style.display = 'none'; 
    this.fieldElement.style.display = 'block'; 
    this.saveButton.style.display = 'inline'; 
    this.cancelButton.style.display = 'inline'; 
 
    this.setValue(this.value); 
}; 
EditInPlaceArea.convertToText = function () { 
    this.staticElement.style.display = 'block'; 
    this.fieldElement.style.display = 'none'; 
    this.saveButton.style.display = 'none'; 
    this.cancelButton.style.display = 'none'; 
 
    this.setValue(this.value); 
}; 
 
augment(EditInPlaceArea, EditInPlaceMixin); 

  


本文参考链接:https://www.cnblogs.com/webFrontDev/archive/2012/12/16/2820379.html