• 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('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.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('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.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');

    效果展示

    最开始时

    点击后

    保存后

    取消后

    原型式继承和掺元类

    基本代码就那些,原型式继承和掺元类的实现只是模式的不同,所以就不再给出具体代码了。

  • 相关阅读:
    [译]6.1. Data Structures Featured in This Chapter 本章涉及到的数据结构
    Linux中进程结构描述符
    How to uninstall GRUB
    [每日一点]msgsnd函数代码跟踪
    开始从代码入手学习内核
    剖析MagicAjax
    Castle实践6-TypedFactory Facility
    移植MSPetShop3到Castle MonoRail -Model与DAL层的移植(AR)
    热血江湖外挂之【热血江湖自补器 Version 0.1】
    对 "闭包closure" 的一些见解
  • 原文地址:https://www.cnblogs.com/JChen666/p/3600852.html
Copyright © 2020-2023  润新知