题记:写这篇博客要主是加深自己对模式代码的认识和总结实现算法时的一些验经和训教,如果有错误请指出,万分感谢。
就上一篇所说的,按道理应当先说说用三种方式(类式继承、原型式继承、掺元式继承)分离实现edit-in-place。懒得敲代码了,所以就用最常用的类式继承实现。其余两种方法就先不说了,如果大家都想看到的话,那我再修改,贴出来吧。最近需要准备练习,完善简历,大巷网上得填写简历去,不知道博客园里头是否会有猎头看到这篇文章,那顺便宣扬一下,大巷网-搜索-哈尔滨工业大学-刘平,就能够找到我,如果大家有好的练习单位,也可以给我私信。


/** * @author tonylp */ function EditInPlaceField(id,parent,value){ this.id = id; this.parentElement = parent; this.value = value || 'default value'; 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.');} }; 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.cancelButton.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; } }; //要创立一个就地编辑域,只需要实例化这个类即可 var titleClassical = new EditInPlaceField('titleClassical',$('doc'),'Title Here'); var currentTitleText = titleClassical.getValue(); //接下来我们要创立一个使用多行文本框而不是单行文本框的类,这个EditInPlaceArea类,这个类继承了EditInPlaceField 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('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.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(); }; 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 = 'block'; this.saveButton.style.display = 'none'; this.cancelButton.style.display = 'none'; this.setValue(this.value); }
1.1 单体模式--javascript中最基本又最有用的模式之一
通过确保单体对象只存在一份实例,你就能够确信自己的所有代码使用的都是一样的全局资源
用途:划分命名空间,增加网页中全局变量的数目,利用分支技术来封装浏览器之间的差异,组织代码,模块化。
单体模式基本结构


var Signleton = { attribute1:true, attribute2:10, method1:function(){ }, method2:function(){ } };
1.2 划分命名空间


// GiantGorp namespace var GiantGorp = {}; GiantGorp.Common ={ // a signleton with common methods used by all objects and modules }; GiantGorp.ErrorCodes = { // An object literal used to store data. }; GiantGorp.PageHandler = { // a signleton with page specific methods and attributes. };
1.3 用作特定网页专用代码的包装器的单体
在具有很多网页的网站中,有些javascript代码是所有网页都要用到的,它们通常被存放在独立的文件中;而有些代码则是某个网页专用品德,不会被用到其他地方。下面是用来包装特定网页专用代码的单体的骨架:


Namespace.PageName = { //Page Constants CONSTANT_1:true, CONSTANT_2:10, //Page methods method1:function(){ }, method2:function(){ }, //Initialization method. init:function(){ } } addLoadEvent(Namespace.PageName.init);
如果大家还记得话,在javascript设计模式探究【1】中,我就讲过用两种方法实现私有成员,下面给出一段模块模式代码(module pattern)--指的是它可以把一批相关方法和属性组织委模块并起到划分命名空间的作用。


MyNamespace.singleton =(function(){ //private member. var privateAttribute1 = false; var privateAttribute2 = [1,2,3]; function privateMethod1(){ ... } function privateMethod2(){ ... } return { publicAttribute1:true, publicAttribute2:10, publicMethod1:function(){ ... }, publicMethod2:function(){ ... } } })();


MyNamespace.singleton =(function(){ var uniqueInstance; function constructor(){ //private member. var privateAttribute1 = false; var privateAttribute2 = [1,2,3]; function privateMethod1(){ ... } function privateMethod2(){ ... } return { publicAttribute1:true, publicAttribute2:10, publicMethod1:function(){ ... }, publicMethod2:function(){ ... } } } return { getInstance:function(){ if(!uniqueInstance){ uniqueInstance = constructor(); } return uniqueInstance; } } })();
说明:惰性加载单体的特别之处在于:对它们的拜访必须借助于一个静态方法,应当这样调用其方法:Singleton.getInstance().methodName();getInstance方法会检查该单体是否已被实例化了。惰性加载单体的缺点是其代码复杂。
1.6 分支--用来把浏览器间的差异封装到运行期间停止设置的动态方法中的技术。


MyNamespace.singleton =(function(){ var objectA ={ method1:function(){ } method2:function(){ } } var objectB ={ method1:function(){ } method2:function(){ } } return (someCondition)?objectA:objectB; })();
分支技术其实不总是更高效的选择,后面的例子中,有两个对象被创立出来并保存在内存中,但是派上用场的只有一个。
1.7 总结
从为代码提供命名空间和增强器模块化的角度考虑,你应当尽量多的使用单体模式,尤其是在网页中包含着形形色色的javascript代码来源。分支技术可以创立高效的方法,不需要管浏览器的兼容性。单体模式提供一种单点拜访,所以它有可能致使模块的强耦合,而且也不利于单元测试。单体模式是一个基本,为后面的各种模式的一个基本。
以上全部都属个人原创,请大家转载的时候附上原创链接: http://www.cnblogs.com/tonylp
文章结束给大家分享下程序员的一些笑话语录: IT业众生相
第一级:神人,天资过人而又是技术狂热者同时还拥有过人的商业头脑,高瞻远瞩,技术过人,大器也。如丁磊,求伯君。
第二级:高人,有天赋,技术过人但没有过人的商业头脑,通常此类人不是顶尖黑客就是技术总监之流。
第三级:牛人,技术精湛,熟悉行业知识,敢于创新,有自己的公司和软件产品。
第四级:工头,技术精湛,有领导团队的能力,此类人大公司项目经理居多。
第五级:技术工人,技术精湛,熟悉行业知识但领导能力欠加,此类人大多为系分人员或资深程序员,基本上桀骜不逊,自视清高,不愿于一般技术人员为伍,在论坛上基本以高手面目出现。
第六级:熟练工人,技术有广度无深度,喜欢钻研但浅尝辄止。此类人大多为老程序员,其中一部分喜欢利用工具去查找网上有漏洞的服务器,干点坏事以获取成绩感。如果心情好,在论坛上他们会回答菜鸟的大部分问题。此级别为软件业苦力的重要组成部分。
第七级:工人,某些技术较熟练但缺乏深度和广度,此类人大多为程序员级别,经常在论坛上提问偶尔也回答菜鸟的问题。为软件产业苦力的主要组成部分。
第八级:菜鸟,入门时间不长,在论坛上会反复提问很初级的问题,有一种唐僧的精神。虽然招人烦但基本很可爱。只要认真钻研,一两年后就能升级到上一层。
第九级:大忽悠,利用中国教育的弊病,顶着一顶高学历的帽子,在小公司里混个软件部经理,设计不行,代码不行,只会胡乱支配下属,拍领导马屁,在领导面前胡吹海侃,把自己打扮成技术高手的模样。把勾心斗角的办公室文化引入技术部门,实在龌龊!
第十级:驴或傻X,会写SELECT语句就说自己精通ORALCE,连寄存器有几种都不知道就说自己懂汇编,建议全部送到日本当IT产业工人,挣了日本人的钱还严重打击日本的软件业!